When you take responsibility for a system you didn't build, the temptation is to begin by finding what's wrong with it.
That usually isn't difficult.
Every mature system contains things you wouldn't have designed yourself. There are old dependencies, strange naming conventions, permissions that seem broader than necessary, services nobody particularly likes and architectural decisions whose original rationale has disappeared.
Finding those things doesn't mean you understand the system yet.
The harder first question is why they're there.
This matters especially when inheriting cloud infrastructure because much of the machinery that would once have been physically visible has moved behind interfaces. Servers still fail. Networks still partition. Credentials still grant authority. Storage still has limits. People still make assumptions. Some responsibilities now appear as permissions instead of keys, dashboards instead of blinking lights, service agreements instead of spare hardware and invoices instead of electric bills.
The underlying operational questions haven't disappeared. Their boundaries have moved.
So I wouldn't spend my first day trying to improve anything.
I'd start by looking.
Identity and access are useful because they show who and what can change the environment. The network begins to reveal which components can communicate and where traffic enters and leaves. Running workloads tell me what the system is actually doing, which may differ considerably from the architecture diagram. Logs and monitoring show what previous operators considered worth observing. Billing can expose expensive workloads, forgotten resources and usage patterns that aren't obvious elsewhere.
None of these provides the whole picture.
Together they give me places to ask better questions.
The people already operating the system are usually the next source of information. I want to know what they worry about, what they avoid touching, what regularly wakes someone up at night and which apparently ugly component has survived three attempted replacements.
That last category is particularly interesting.
Sometimes ugly infrastructure is simply ugly infrastructure.
Sometimes it contains a lesson nobody documented.
A strange retry policy may exist because a vendor once behaved in an unexpected way. A manual deployment step may be needless friction, or it may be the remaining protection against an automation failure that caused an expensive incident five years ago. An apparently redundant database field may still support some customer workflow nobody remembered to mention.
I don't want to romanticize inherited complexity.
I want to recover the problem before deleting the solution.
That changes the tone of early technical conversations. Basic questions aren't accusations if they're genuinely questions.
What has to be true before we ship?
What happens if this service disappears?
Where does customer data go after it enters the application?
Who can read it?
Who can change production?
What happens if a vendor changes its API, pricing or availability?
Which failure have you already designed around?
Which failure do you know you haven't?
What part of this architecture would you least like to explain during an incident?
The answers gradually produce a working model of the system.
Some of that model is technical. Some isn't.
A perfectly redundant service may still depend on one employee who knows how to recover it. A database may have excellent backups nobody has restored recently. An application may tolerate the loss of three servers while depending completely on one external API. A sophisticated monitoring system may report hundreds of metrics without answering the question everyone actually asks during an outage.
This is why I find failure boundaries more useful than technology inventories.
Knowing that a system uses Kubernetes, PostgreSQL, Redis and a particular cloud provider tells me what it's made from.
Knowing what happens when each part disappears tells me considerably more about how it behaves.
I can work outward from there.
What happens when a process dies?
What happens when the machine underneath it disappears?
What happens when storage becomes unavailable?
What happens when the network between two otherwise healthy components fails?
What happens when an administrator makes a mistake?
What happens when a credential leaks?
What happens when the vendor itself becomes unavailable?
Not every system needs a satisfying answer to every question.
Resilience costs money and complexity. A startup serving a few hundred customers probably shouldn't build infrastructure as though it operates an international payment network. Some failures can reasonably cause downtime. Some data can be reconstructed. Some services can remain unavailable until morning.
The important thing is knowing which compromises we've made.
That applies to my own tools too.
I want a workstation that lets me inspect the environment without quietly becoming part of the environment's availability model. Credentials should be managed deliberately. Administrative access should be understandable and revocable. Important procedures shouldn't depend on something I happen to remember.
If losing my laptop creates an inconvenience, that's normal.
If losing it makes production unrecoverable, I've discovered an architectural problem.
As I understand more of the system, I start looking closely at boundaries between components. A request enters through an interface, reaches an API, causes a database change, publishes an event and eventually triggers another service.
Every transition introduces assumptions.
What format is expected?
What establishes identity?
What happens if the message arrives twice?
What happens if it never arrives?
What happens if the first operation succeeds and the second doesn't?
Who owns the data at this point?
How would we reconstruct what happened afterward?
These questions don't make boundaries inherently dangerous. Interfaces are how complicated systems become manageable. They allow one component to change without requiring everything around it to change simultaneously.
The boundary is useful precisely because it hides something.
My job is to understand what we've chosen to hide and what still has to remain visible.
Managed services work the same way. They can remove enormous amounts of undifferentiated operational work. I may be very happy to let someone else operate hardware, replace disks, mitigate attacks or maintain a globally distributed service.
That doesn't mean we've surrendered responsibility for everything above that boundary.
We still decide how data is structured, which permissions we grant, what dependencies we accept and what happens to our application when the service doesn't behave as expected.
Sometimes accepting a strong external dependency is entirely reasonable.
Not every vendor needs a redundant substitute waiting behind it.
Redundancy itself has a cost, and maintaining two poorly understood implementations may produce more risk than relying on one mature service with a well-understood failure mode.
The question isn't whether an external service is a single point of failure.
It's whether we're comfortable with what happens when that point fails.
AI belongs in the same analysis.
An AI system may summarize information, generate code, classify requests, recommend actions or perform increasingly complicated tasks. What matters operationally is what authority we've given it and what happens when its output is wrong.
If it drafts text that a person reviews, the failure boundary looks one way.
If it can change a customer's account directly, it looks very different.
I want to know what information the model receives, what actions it can take, what gets recorded, which decisions can be reversed and what happens when the model or provider is unavailable.
I don't need to decide from first principles whether AI is an advisor or a decision-maker.
The architecture tells me what role we've actually given it.
Then I can ask whether that role is appropriate.
Over the first few weeks, patterns begin to emerge. Some parts of the system are stable because they're well understood. Others are stable because nobody dares touch them. Some external dependencies save the team enormous amounts of work. Others have quietly accumulated enough importance that their failure would now threaten the business.
That's when architectural changes start becoming easier to justify.
Maybe we need another copy of some data.
Maybe we need better access controls.
Maybe an old service should finally be replaced.
Maybe the expensive cloud component everyone complains about is worth every dollar because operating it ourselves would distract the team from work that matters more.
Maybe the thing I wanted to rewrite during my first week makes considerably more sense by week six.
And occasionally it makes even less sense.
Now I have evidence.
The same restraint applies to scale.
It's useful to ask what happens at two, five or ten times the current workload, but I don't want to build all three systems in advance. Predictions about future scale are assumptions too.
Some preparations are inexpensive and preserve options. Others create complexity today in anticipation of a future that may never arrive.
A schema that's difficult to migrate deserves attention early.
Buying ten times the infrastructure because we might someday need it probably doesn't.
The distinction depends on the cost of changing later.
That's really what I'm trying to learn during the first ninety days.
Which decisions are easy to reverse?
Which become expensive quickly?
Which failures are tolerable?
Which could threaten the business?
Which strange pieces of the inherited system contain useful knowledge?
Which merely survived because nobody had enough reason to remove them?
There doesn't need to be a rigid ninety-day sequence. An exposed credential may need attention on the first afternoon. A major architectural decision may deserve three months of observation. Some inherited systems are healthy enough that the best early contribution is leaving them alone.
The calendar doesn't determine the intervention.
Evidence does.
If the process goes well, the system gradually becomes easier to explain. Risks have names. Tradeoffs become explicit. Recovery procedures are tested. Decisions that used to live in one person's memory begin to survive without that person being present.
The team also learns something about me.
I'm willing to change things.
I just want to know what we're changing first.
Eventually there will be plenty to build. Some old components will disappear. New services will arrive. Responsibilities will move. The architecture that seemed permanent when I inherited it may look very different a few years later.
That's fine.
The objective was never to preserve the inherited system.
It was to understand it well enough that when we change something, we have some idea what we're giving up along with what we're gaining.
Before I make the system better, I want to know why it became this system.