Category: Freelancing

  • Case study 19: When Code Breaks a Client’s Website: How Programmers Should Communicate During a Production Incident

    The code failed. The communication shouldn’t.

    Every programmer eventually makes a mistake.

    Sometimes it is a small bug that affects one button. Sometimes it is a database query that returns the wrong result. And sometimes, especially when working directly on a live website, a mistake can make an entire website appear broken.

    For a programmer, the technical problem may be understandable: a misplaced function, a bad configuration, an unexpected server response, or a plugin conflict.

    For the client, however, the situation is very different.

    They may see a blank website.

    They may be unable to access WordPress administration.

    They may worry that their data is gone.

    They may wonder whether their business is losing customers.

    And they may immediately ask:

    “What happened?”

    At that moment, technical ability is only half of the job.

    The other half is communication.

    A lesson from a real freelance project

    Early in my freelance work, I experienced a situation that taught me an important lesson about communicating during technical incidents.

    A client hired me to develop a WordPress plugin that would generate an XML feed from their website and synchronize advertisements with another property platform.

    The project was relatively small. The agreed price was $30, with a three-day delivery period and source code included.

    While developing the plugin, I made a mistake in the code. An exit() statement had been placed incorrectly.

    The result was serious: the client’s live WordPress website became inaccessible.

    The client reported that the website was blank and that even the WordPress administration area was not working correctly.

    Naturally, the client’s reaction was emotional.

    From the developer’s perspective, the underlying problem was identifiable and potentially recoverable. From the client’s perspective, however, their website was down.

    That distinction is extremely important.

    Technical reality and client reality are different

    A programmer might think:

    “The plugin is causing the problem. We simply need to disable it.”

    The client might think:

    “My website has disappeared. Is my data safe? Is my business website destroyed? Who is going to pay for this?”

    Both perspectives are understandable.

    The programmer sees the cause.

    The client sees the impact.

    Good communication connects those two perspectives.

    One of the messages I sent at the time was essentially:

    “Your website is ok, we need to remove the plugin.”

    Technically, I was trying to reassure the client.

    But looking back, that was not the best wording.

    If the client is looking at a blank website, telling them that the website is “OK” can sound as though the developer is denying the problem.

    A better approach would have been:

    “I understand that the website is currently blank. I have identified the plugin as the cause. The website files and content should still be intact, and the immediate step is to disable the plugin so we can restore normal access.”

    That message does several things:

    • acknowledges the visible problem;
    • takes responsibility;
    • explains what has been identified;
    • reduces unnecessary panic;
    • provides a recovery direction.

    That is much more effective communication.

    The Five-Step Incident Communication Framework

    When your code causes a problem on a client’s live system, use this simple framework:

    Acknowledge → Own → Explain → Recover → Prevent

    Let’s examine each step.

    1. Acknowledge the problem

    Start with what the client is experiencing.

    Don’t immediately start talking about PHP functions, WordPress hooks, database queries, server configuration, or XML.

    Say:

    “I understand that the website is currently showing a blank page.”

    This confirms that you understand the problem.

    It also prevents the client from feeling ignored.

    During an incident, the first communication should answer:

    “Do you understand what is happening?”

    Only after that should you move into technical details.


    2. Own the mistake

    If your code caused the problem, say so clearly.

    Avoid language such as:

    • “Something happened.”
    • “The server is acting strange.”
    • “Maybe HostGator caused it.”
    • “WordPress is having an issue.”
    • “It could be a plugin conflict.”

    If you already know your code is responsible, don’t hide behind uncertainty.

    A professional message is:

    “I found an issue in the plugin code that is causing the website to stop loading. This is my mistake, and I will focus first on restoring the website.”

    Taking responsibility does not make you look weak.

    In fact, it often establishes trust.

    Clients generally understand that programmers can make mistakes. What damages confidence is when the programmer appears to avoid responsibility.


    3. Explain the technical cause — but in the right amount

    Once the immediate situation is acknowledged, explain the cause.

    In this case, the issue involved an incorrectly placed exit() function inside a new WordPress plugin.

    A technical explanation could be:

    “The plugin contains an exit() call in the wrong execution path. Because the plugin is loaded by WordPress, the statement interrupts normal page execution and results in the blank page.”

    That is useful.

    But the explanation should not become a lecture.

    The client usually doesn’t need to understand PHP execution flow while their website is unavailable.

    Think about the difference between these two messages:

    Too technical:

    “The exit() function is terminating execution before WordPress completes the template lifecycle, probably because the hook is being executed globally.”

    Better:

    “I found an error in the new plugin that stops WordPress from completing the page request. I know where the problem is and am working on disabling the affected component first.”

    The second message communicates the same essential information without overwhelming the client.


    4. Give a recovery plan

    This is perhaps the most important part.

    When a website is down, don’t send ten possible solutions.

    Give the client a clear sequence.

    For example:

    Step 1: Disable the affected plugin.

    Step 2: Confirm that the website loads again.

    Step 3: Inspect and correct the plugin code.

    Step 4: Test the corrected plugin on a safe environment.

    Step 5: Only then reinstall or reactivate it on the live website.

    This is much better than sending a series of disconnected instructions.

    During a production incident, the client wants to know:

    “What happens next?”

    Answer that question explicitly.


    5. Explain how you will prevent a repeat

    After the website is restored, don’t simply say:

    “Fixed.”

    Explain what changed.

    For example:

    “The plugin has been corrected and tested separately. I have also removed the execution path that caused the page to stop loading. Before reactivating it on the live website, I will test the feed generation and WordPress admin functionality.”

    This demonstrates that you are not merely patching the symptom.

    You are addressing the underlying problem.

    Don’t make the client troubleshoot your code

    One of the lessons I learned from this experience is that developers should be careful about transferring technical responsibility to the client during an incident.

    Asking a client to:

    “Remove this folder from wp-content/plugins/”

    may be technically valid.

    But if the client isn’t a developer, they may not be comfortable working inside the hosting filesystem.

    A better approach is to explain why the action is needed:

    “The problem is isolated to the new domaza_xml_feed plugin. Temporarily disabling that plugin should allow WordPress to load normally. If you can provide temporary FTP or hosting access, I can perform the change myself.”

    This is much more reassuring.

    The client understands:

    • what is being changed;
    • why it is being changed;
    • what the expected result is;
    • and who is responsible for the fix.

    Avoid promises like “I’ll fix it in no time”

    When a website is down, developers sometimes try to reassure clients with statements such as:

    “I will fix it in no time.”

    The intention is good.

    The problem is that it creates an unnecessary promise.

    What if the hosting environment introduces another issue?

    What if the backup is unavailable?

    What if the problem is more complicated than initially expected?

    Instead, communicate the next concrete action:

    “My first priority is to restore the website. I will disable the affected plugin and then investigate the code separately.”

    That is confident without making an unrealistic guarantee.

    Never send ten messages when one clear message will do

    Another common mistake during stressful situations is sending message after message.

    For example:

    “Please share hosting access.”

    Then:

    “FTP access would be better.”

    Then:

    “Please ask your hosting provider.”

    Then:

    “Please disable the plugin.”

    Then:

    “Give me one chance.”

    The developer may be trying to help, but to the client it can look like uncertainty.

    A better communication pattern is:

    What happened → What I found → What I will do → What I need from you.

    For example:

    “I identified the new plugin as the cause of the blank page. The issue is related to an execution statement in the plugin code. I need to disable the plugin first to restore the website. If you can provide temporary FTP access, I can do this directly; otherwise, your hosting provider can disable the plugin using the plugin folder name domaza_xml_feed.”

    One message.

    Clear.

    Actionable.

    Professional.

    What about an angry client?

    Clients may write in capital letters.

    They may ask:

    “WHAT DID YOU DO?”

    They may ask:

    “WHO WILL PAY ME?”

    They may blame the developer.

    Your response should not mirror their emotional tone.

    Don’t argue.

    Don’t write:

    “Calm down.”

    Don’t say:

    “It’s not a big problem.”

    Don’t immediately defend yourself.

    Instead:

    “I understand why you’re concerned. The website is currently affected by the plugin I was developing, and I take responsibility for correcting the issue. My immediate priority is to restore the website.”

    This changes the conversation from blame to resolution.

    The importance of testing before touching production

    There is also a technical lesson behind the communication lesson.

    If you are developing a WordPress plugin that can affect the entire website, avoid treating the client’s live website as your development environment whenever possible.

    A safer workflow is:

    Development → Staging → Testing → Backup → Production

    Before activating a new plugin on production:

    • take a backup;
    • test the plugin on staging;
    • verify WordPress admin access;
    • test the homepage;
    • test important custom post types;
    • test database operations;
    • test feed generation;
    • check PHP errors;
    • verify that disabling the plugin restores normal operation.

    For small freelance projects, you may not always have a complete staging environment.

    But you can still create a safer process.

    Even a local WordPress installation or temporary test environment is better than experimenting directly on a client’s live business website.

    Communication is part of programming

    A common misconception among new programmers is that their job is simply to write working code.

    It isn’t.

    Professional software development also involves:

    • understanding requirements;
    • setting expectations;
    • documenting changes;
    • communicating risks;
    • reporting progress;
    • handling failures;
    • explaining technical decisions;
    • and taking responsibility when something goes wrong.

    A developer who writes excellent code but communicates poorly can still create a poor client experience.

    Likewise, a developer who makes an occasional mistake but communicates clearly, takes responsibility, and fixes the problem professionally can maintain a strong working relationship.

    The goal isn’t to become a programmer who never makes mistakes.

    The goal is to become a programmer who knows how to respond when mistakes happen.

    A practical emergency message template

    New programmers and freelancers can keep a template like this available:

    Hi [Client Name],

    I understand that the website is currently affected, and I have identified the issue as coming from the code I recently added.

    I take responsibility for the problem. My first priority is to restore the website, so I recommend temporarily disabling the affected component.

    Once the website is back online, I will investigate and correct the code separately and test the fix before activating it again.

    If you can provide temporary [FTP/hosting/staging] access, I can handle the recovery directly.

    I will keep you updated on the progress and explain the final cause and fix once the issue is resolved.

    Regards,
    [Your Name]

    The template can be adapted depending on the situation.

    The important part is the structure, not the exact wording.

    Five rules every new programmer should remember

    When your code causes a production problem:

    1. Don’t hide the mistake.
    If your code caused it, acknowledge it.

    2. Don’t overwhelm the client with technical details.
    Explain the cause at the level necessary to understand the situation.

    3. Don’t argue about whether the problem is “serious.”
    Focus on restoring the service.

    4. Don’t give multiple conflicting instructions.
    Give one clear recovery plan.

    5. Don’t stop communicating after the fix.
    Explain what happened, what you changed, and how you will reduce the chance of recurrence.

    The bigger lesson

    That 2023 WordPress project was not an example of perfect development.

    It was an example of something more useful: learning from a real production mistake.

    The technical mistake was relatively simple.

    The larger lesson was about professional responsibility.

    When a developer’s code affects a client’s website, the client doesn’t need a perfect programmer.

    They need a programmer who is:

    honest, calm, clear, accountable, and focused on recovery.

    Years of programming experience teach you that bugs are unavoidable.

    Professionalism is demonstrated by what you do next.

    The best developers don’t communicate only when everything works.

    They communicate especially well when something doesn’t work.

    And sometimes, the most valuable lesson from a broken website isn’t found in the code.

    It is found in the conversation that follows.

  • When Working From Home Looks Like Doing Nothing

    Working from home is often presented as a modern advantage: no commute, greater flexibility, more time with family, and the freedom to organize your own schedule.

    But there is another side to working from home that is rarely discussed.

    Sometimes, the people closest to you are the ones who understand it the least.

    I learned this in a painful way when I realized that my father had become convinced that I was simply sleeping or relaxing at home all day.

    The irony was that I was not working less. In many periods, I was working more.

    The Invisible Nature of Remote Work

    One of the biggest problems with working from home is that the work itself becomes invisible.

    When someone leaves home in the morning, travels to an office, spends eight or ten hours there, and returns in the evening, everyone understands the basic story:

    He went to work.

    There is a physical place associated with the work.

    There are colleagues.

    There is a desk.

    There are meetings.

    There is a visible separation between “work time” and “home time.”

    A person working from home has none of those visible signals.

    If you are sitting at your computer at 10 in the morning, someone may see you as “being at home.”

    If you are still working at 11 at night, they may simply see you as someone who happens to be using a computer.

    The actual work—problem solving, communication, debugging, planning, documentation, testing, dealing with clients, meeting deadlines—is mostly invisible.

    And invisible work is surprisingly easy to undervalue.

    When Your Own Family Misunderstands Your Work

    What makes this particularly difficult is when the misunderstanding comes from the people you love the most.

    In my case, my father became convinced that I was spending my days sleeping rather than working.

    That belief did not come from nowhere.

    It was shaped by what he heard and understood from people around me—my wife and relatives, people I love and care about deeply.

    That is what made the situation difficult.

    I don’t believe they were deliberately trying to diminish my work.

    From the outside, working from home can genuinely look very different from traditional employment.

    There is no office building to point to.

    There is no manager physically watching the work.

    There is no commute proving that you have “gone to work.”

    And there may be no obvious physical evidence of what you accomplished that day.

    The result is a strange situation:

    You can be working extremely hard while appearing to be doing almost nothing.

    The Productivity Paradox

    Remote work has a peculiar paradox.

    The better you become at organizing your work, the less visible the effort may become.

    A freelancer or remote professional may spend hours solving a problem that eventually produces only a few lines of code.

    A client may see the final feature, but not the hours spent understanding the requirement, researching the problem, testing different approaches, fixing unexpected issues, documenting the solution, and testing it again.

    Similarly, a person may spend an entire day dealing with difficult technical problems and finish the day without anything visually impressive to show.

    The computer screen looks almost exactly the same.

    But the person has moved the project forward significantly.

    This is particularly true in technical work.

    Writing code is often the smallest part of the job.

    Understanding a system, diagnosing failures, designing architecture, testing edge cases, communicating with clients, maintaining existing systems, and taking responsibility for the final result can consume far more time than simply typing code.

    Yet none of that is visible from the outside.

    The Emotional Cost

    Being misunderstood by strangers is one thing.

    Being misunderstood by your own family is different.

    When people you love believe that you are not working seriously, it can slowly affect how you see your own work.

    You may begin feeling that you have to constantly prove that you are working.

    You may feel guilty when you take a break, even though breaks are normal.

    You may hesitate to spend time with your children because you feel that someone might interpret it as evidence that you are not working.

    You may continue working late simply because you feel that the visible appearance of “being busy” is necessary.

    And eventually, something that was supposed to provide flexibility can become another source of pressure.

    This is one of the hidden problems of working from home:

    You are not only managing your work. You are also managing other people’s perception of your work.

    Family Often Measures Effort by Visibility

    Perhaps the deeper lesson is that families often measure effort through visible sacrifice.

    Someone leaving home early every morning appears disciplined.

    Someone returning late appears hardworking.

    Someone sitting at home behind a laptop does not necessarily receive the same recognition—even if that person is working just as hard.

    This is not necessarily because people are unfair.

    It is because humans naturally use visible signals to judge invisible activity.

    The problem is that remote work removes many of those signals.

    A person can work for ten hours and still appear available.

    That availability can create another misunderstanding:

    “If you are home, you must be free.”

    But being physically present is not the same as being mentally available.

    The People We Love Can Hurt Us Without Intending To

    There is another uncomfortable realization in this experience.

    Sometimes the people who contribute to our biggest misunderstandings are not our enemies.

    They are the people we love.

    My father was not trying to insult my profession.

    My wife and relatives were not necessarily trying to undermine me.

    They were interpreting what they could see.

    And what they could see was very different from what I was actually experiencing.

    That distinction matters.

    It is easy to become angry and say, “They don’t understand how hard I work.”

    But a more useful question is:

    Why is my work so difficult for them to see?

    That question leads to a better conversation.

    What Remote Professionals Can Learn

    My experience has taught me that remote workers should not assume that their families automatically understand what they do.

    We may think our work is obvious because we live it every day.

    It isn’t.

    Sometimes we need to explain it.

    Not defensively.

    Not by listing every hour we worked.

    But by helping people understand what actually happens behind the screen.

    Instead of saying, “I work all day,” explain what that work means.

    “I have a client deadline.”

    “I need to diagnose this technical problem.”

    “I have testing to complete.”

    “I have to deliver this feature today.”

    “I have a meeting at this time.”

    These small explanations can make invisible work more visible.

    Working From Home Is Still Work

    The location of work does not determine its value.

    A person can work from an office and be unproductive.

    A person can work from a bedroom, living room, or home office and build something valuable.

    The important question should not be:

    “Where are you working?”

    It should be:

    “What are you accomplishing?”

    For freelancers and remote professionals, the answer may not always be immediately visible.

    But that does not make the work less real.

    A Personal Conclusion

    I don’t want this experience to become a complaint about my father, my wife, or my relatives.

    They are people I love and care about.

    Instead, I see it as a lesson about how easily invisible work can be misunderstood—even by the people closest to us.

    Perhaps my father seeing me at home and thinking I was sleeping was, in its own way, a reminder of just how invisible my work had become.

    I had spent years building a career around a computer.

    My workplace had become my home.

    My colleagues were often on the other side of a screen.

    My clients were in different places.

    My workday did not always have a clear beginning or end.

    And the results of my work often existed only as code, files, emails, systems, and completed projects.

    There was no office door to close at the end of the day.

    There was no uniform, factory, shop, or desk that announced:

    “This person is working.”

    So perhaps the real challenge of working from home is not productivity.

    It is visibility.

    And perhaps one of the most important things remote workers can learn is this:

    Your work does not become less valuable simply because other people cannot see the effort behind it.

    Sometimes, you have to trust the value of what you are doing—even when the people you love do not fully understand it yet.

  • How a Client Got a Full Refund Six Months After an Order Was Completed — And What I Learned

    As a freelancer, one of the hardest lessons to learn is that finishing a project does not always mean the project is truly finished.

    I recently experienced a situation where a client received a completed project, the order was accepted, and the original scope had effectively been delivered. Months later, however, the client requested significant changes to the project.

    What followed eventually resulted in a full refund of the original order amount — approximately six months after the order had been completed.

    This experience changed the way I think about project scope, revisions, acceptance, documentation, and what freelancers should do when a client wants to fundamentally change an already completed project.

    The project was completed

    The project originally had a defined scope and price.

    I completed the work according to that scope, delivered the agreed functionality, and the client accepted the order.

    At that point, from a normal freelance-project perspective, the transaction should have been closed.

    The important lesson here is that an accepted order creates a psychological sense of finality, but freelancers should not assume that the risk has completely disappeared.

    I now believe that completion and acceptance are only one part of protecting yourself.

    The other part is maintaining a clear record of:

    • What was originally requested
    • What was actually delivered
    • What the client approved
    • What revisions were included
    • What changed later
    • When those changes were requested
    • Whether the new request materially changed the architecture or workload

    Then the requirements changed

    Several months after the original order was completed, the client requested a major change.

    This was not simply a small correction or a minor bug fix.

    The requested change affected the underlying way the system obtained and processed its data.

    Initially, I treated the request as a goodwill gesture rather than immediately treating it as a completely new project.

    That decision is something I have thought about a lot since then.

    As a freelancer, it is natural to want to help a long-term client.

    You think:

    “I already know the project. I’ll take care of this small change.”

    The problem is that something that looks small from the client’s perspective can become a completely different engineering problem.

    A change in the data source, architecture, workflow, validation requirements, or external dependencies can have consequences throughout the entire system.

    What starts as “just change the source” can become:

    new ingestion → new parsing → new normalization → new caching → new testing → new diagnostics → new failure handling → new documentation → new acceptance criteria.

    At that point, it is no longer simply a revision.

    It is a new engineering phase.

    The hidden cost of saying “I’ll do it for free”

    This was probably the biggest lesson for me.

    When I agreed to look into the change without immediately charging a new project fee, I intended to provide good customer service.

    Instead, I gradually became responsible for work that was significantly larger than the original request.

    The more I investigated the new requirements, the more complexity became visible.

    There were new technical questions, testing requirements, external-source issues, diagnostics, caching considerations, and additional acceptance expectations.

    The amount of engineering effort grew substantially.

    And this created an uncomfortable situation:

    The client viewed the work as a continuation of the original project.

    I increasingly viewed it as a materially different project.

    That difference in perception is dangerous.

    The most important lesson: define “change” before doing it

    A freelancer should not ask only:

    “Can I technically make this change?”

    The more important question is:

    “Does this change remain inside the original commercial scope?”

    Those are two completely different questions.

    A technically possible change can still be commercially outside the original agreement.

    For example, these may look like minor requests:

    • “Use another source.”
    • “Change the input format.”
    • “Add another validation layer.”
    • “Make it work with this external service.”
    • “Add comprehensive unit testing.”
    • “Add diagnostics.”
    • “Provide evidence for every component.”
    • “Change the architecture.”

    But each can potentially create substantial additional work.

    The freelancer has to identify that boundary early.

    Six months changes the situation — but does not eliminate risk

    One of the most surprising parts of this experience was the timing.

    The original order had been completed approximately six months earlier.

    From the freelancer’s perspective, the project was old.

    From the client’s perspective, however, the client was still looking at the overall project and raising concerns about what they believed remained incomplete.

    That taught me something important:

    Time alone does not protect a freelancer from a scope dispute. Documentation does.

    A freelancer should be able to open the project history months later and immediately demonstrate:

    1. What the original agreement said.
    2. What was delivered.
    3. What the client accepted.
    4. What changed afterward.
    5. Why the later request required additional work.

    Without that record, a dispute can become a matter of interpretation.

    The full refund was the hardest lesson

    Eventually, the situation resulted in a full refund of the original order amount.

    For a freelancer, this is more than simply losing the money.

    There is also the opportunity cost.

    The time spent investigating, developing, testing, documenting, communicating, and trying to resolve the dispute cannot be recovered.

    And if substantial unpaid work has been performed after the original order, the freelancer can end up in an especially difficult position:

    The original project has already been delivered, but the freelancer has also invested significant additional time trying to accommodate a later change — and ultimately receives nothing for either phase.

    That is an extremely expensive lesson.

    What I would do differently now

    If I faced the same situation again, I would handle it differently.

    1. Freeze the original scope

    Once an order is completed and accepted, I would clearly distinguish between:

    Original scope

    and

    New requested work.

    I would not automatically assume that a later request is a revision.

    2. Perform a change-impact assessment

    Before writing code, I would explain:

    “I can investigate this change, but first I need to determine whether it can be implemented within the existing architecture and scope.”

    That small sentence can prevent a major misunderstanding.

    3. Separate investigation from implementation

    Investigation itself can require significant engineering time.

    A better process is:

    Phase 1 — Assessment

    Determine feasibility, architecture impact, estimated effort, risks and dependencies.

    Phase 2 — Proposal

    Provide a separate price and timeline.

    Phase 3 — Implementation

    Begin development only after the new scope is approved.

    This prevents “free investigation” from quietly turning into months of unpaid development.

    4. Never rely on goodwill as a substitute for scope

    Goodwill is valuable.

    But goodwill should have boundaries.

    A freelancer can say:

    “I’ll take a quick look at this as a courtesy.”

    But that should not automatically become:

    “I’ll rebuild the system around this new requirement for free.”

    5. Put material changes in writing

    If the client changes an important requirement, document it explicitly.

    For example:

    “The original implementation used Source A. You are now requesting Source B. This changes the ingestion architecture and therefore requires additional development.”

    That single statement establishes a written record of the change.

    6. Don’t let sunk costs dictate the next decision

    Another trap is thinking:

    “I’ve already spent 30 hours on this, so I should keep going.”

    That can become:

    30 hours → 50 hours → 80 hours → 100 hours.

    At some point, continuing is no longer protecting the original investment.

    It is increasing the loss.

    A better question is:

    “If I had not already spent any time on this, would I agree to take on this new scope for the current price?”

    If the answer is no, stop and renegotiate.

    What clients can learn from this too

    This is not only a freelancer lesson.

    Clients also benefit from clearly separating:

    bug fixes,
    revisions, and
    new requirements.

    A freelancer should not be expected to absorb an architectural change simply because the change relates to the same product.

    If the underlying requirement changes, the commercial agreement may need to change as well.

    That is not necessarily a sign of a difficult freelancer.

    It is often simply good project management.

    The real lesson

    The biggest lesson I took from this experience is not:

    “Never help a client.”

    It is:

    “Help clients, but never allow goodwill to replace a clearly defined scope.”

    I still believe that good freelancers should be flexible.

    Sometimes you should fix something without charging.

    Sometimes you should help a client with a small change.

    Sometimes you should go beyond the written requirements because building a good relationship matters.

    But there needs to be a clear boundary between customer service and taking responsibility for an entirely new project.

    When that boundary disappears, everyone can end up with a different understanding of what was agreed.

    And when that disagreement surfaces months later, the freelancer may discover that the cost of being generous was much higher than expected.

    My advice to other freelancers

    If you are a freelancer, especially if you work on custom software or development projects, I would strongly recommend keeping a simple project record containing:

    • Original scope
    • Original price
    • Delivery date
    • Acceptance date
    • Client approvals
    • Revision history
    • New requirements
    • Change requests
    • Additional estimates
    • Additional approvals
    • Major technical decisions
    • Final delivery evidence

    And perhaps most importantly:

    Do not start substantial work on a materially different requirement simply because you want to be helpful.

    First determine what changed.

    Then determine what it will take.

    Then agree on the new scope.

    Then start.

    Because sometimes the most expensive sentence a freelancer can say is:

    “Don’t worry, I’ll do this one for free.”