I Built a Framework Because I Couldn’t Move My Own App
A while back I tried to move the Virtual CTO Advisor off Google Cloud and onto an NVIDIA Spark sitting on my desk. That move did not go the way I expected. A pile of things I had taken for granted while building the application turned out to be dependencies I had never written down as requirements, and when I went to lift the app, those dependencies came to light all at once. That failure is where the 4+1 AI Infrastructure model came from. I built the framework to name the thing that had just bitten me.
This is me going back to the same catalyst, except now I am armed with the language and the tooling that the first attempt forced me to build. I gave myself a mock business requirement to make it concrete: a vendor I work with asks me to move the Virtual CTO Advisor off Google Cloud onto another platform. I have no commercial arrangement that requires me to host it anywhere in particular, so the request is fair. As pre-work for that mock migration, I pointed the 4+1 assessment at my own application and looked for the drift in design and operations that I never considered when I first built it.
I want to be honest about what the Virtual CTO Advisor is, because it matters. It is the poster child for the thing I warn against when I talk about designing AI apps. It is the proof of concept you build, get working on your laptop, and move into production without really considering all the things you should. It is not a toy — it has a retrieval pipeline, an ingestion system, an identity layer, and a reasoning loop running over thousands of pieces of content. But it grew from a prototype that worked, not from requirements that accounted for what it would take to run or move it. It is the prototypical 4+1 application precisely because it is the one I built the model on.
What I was actually running
When you read it against the 4+1 layers — compute, data, retrieval, pipelines, orchestration, runtime, reasoning, application — the pieces map cleanly. Firestore holds the conversation data. Discovery Engine holds the search index. A set of scheduled jobs harvest content into Cloud Storage and format it into the index. Firebase Authentication handles identity. GKE runs the services. Gemini, through Vertex AI, does the reasoning, and Google Search grounds the responses in fresh citations.
The interesting part is not the architecture. It is what happens when you impose 4+1, and specifically DAPM, on top of it. DAPM asks one question at every layer: what authority did I retain, delegate, or cede? When I built the app I did not have that language. I did not have a way to see what authority I was handing to Google as I went. It was not until I tried to move the application that I understood how much of it depended on infrastructure I had taken for granted. None of my original requirements took these services into account.
What the test caught
| Layer | What I run | Authority | Ceded or decided |
|---|---|---|---|
| Compute | Cloud-managed abstractions | Ceded | Not drift — I never wanted to manage physical compute |
| Storage | Firestore (after GCS) | Ceded | Ceded — the origin decision |
| Retrieval | Discovery Engine | Ceded | Ceded — bound by storage |
| Pipelines | Cloud Storage + harvest jobs | Ceded | Ceded — ingestion, chunking, indexing, embedding, search |
| Orchestration | GKE | Ceded | Ceded — low impact, GKE is Kubernetes |
| Runtime | Gemini via Vertex AI | Ceded | Decided on purpose |
| Reasoning (2C) | Google’s placement layer | Ceded | Ceded — and I did not know it existed |
| Identity (+1) | Firebase Auth | Ceded | Decided on purpose |
Layer zero is not a debate. It does not matter which public cloud I run on — I have no desire to manage physical network, storage, and compute. I want to describe the abstractions and let the provider supply them. No drift there.
The real drift starts at storage. In the initial design this was simple: I needed to ingest my data, so I imported it into object storage in GCS. Straightforward, S3-compatible, fine. But as the application grew and I needed a platform estate, I defaulted to Firestore — and that was the decision that ceded the authority of everything that followed. I did not have the language or the knowledge to understand what that meant downstream, and it bound every decision after it. Retrieval now had to depend on the Firestore and GCS combination. That in turn bound the pipeline, which meant I had ceded my entire ingestion path through Cloud Run — my chunking strategy, my indexing strategy, my embedding strategy, my search strategy — all ceded to Google without once asking what happens if I ever have to move. It was convenient, and I probably would not have changed the architecture even if I had asked. But I ceded the authority in a way that caused the drift, rather than deciding it.
Orchestration is the one place the drift is real but the impact is small. I use GKE. I could not care less about Kubernetes as a thing to manage — container build, scheduling, orchestration all run through GKE — but at its core it is Kubernetes, and moving from GKE to another Kubernetes-compliant runtime is straightforward. The capability is ceded to Google. The cost of unwinding it is low. So I note it and move on.
Two placements were not drift at all. Using Gemini through Vertex AI was a deliberate design decision — different from choosing OpenAI or Anthropic, or even calling Gemini through plain API calls instead of Vertex, and I made it on purpose because I was already all-in on Google. And identity, which is really the plus-one that rolls through everything, I ceded to Google authentication on purpose. Those were decisions. I weighed them. They are healthy cessions because I made them.
Then there is the elephant in the room: layer 2C. Google has a fairly complete 2C offering — the reasoning and placement layer that decides where compute goes based on storage requirements, policy, and the rest. As an application builder I do not want to make those routing decisions by hand. I want to write organizational policy and opinions and let the platform place the workload. The problem is that when I built the application, I had no idea this layer existed. This was me learning how to use AI. So I did not just cede this authority to Google — I ceded authority I did not know I had to give. That is the real drift, and it is exactly the dependency that came to light when I tried to move to the Spark. This layer is where 4+1 came from.
What the model told me, and what it did not
The model was good at the thing it was built for. It identified the drift and predicted where that drift would bite if I moved the application — to AWS, to Azure, to on-premises, to the Spark. Point the assessment at the app, hold it against what each destination actually offers, and the cessions you never decided show up as the work you would have to do.
Where it reached its edge is day-two operations. The model says nothing about the authority drift in running the application. How do I do CI/CD if I am on Cloud Build today — how does that translate to AWS, or to Azure? What does logging look like? Security alerts? The control plane, if I want to grant rights to this application to other developers and administrators? None of that is in the 4+1 read, and the migration is what made the silence obvious.
That edge is not a flaw to paper over. It is the boundary of what the model is for. The 4+1 model identifies the components you need to build an application. It does not identify the authority you need to assign to run one. That is a different domain, and that work is for the greater community to do. Finding the edge of your own framework by stressing it against something real is supposed to be one of the outcomes. This is one.
The part worth sitting with
Drift is a bill you have not been handed yet. Everything works today, so the ceded authority costs nothing — until something forces it to resolve. A migration is one thing that forces it. So is a feature you cannot build on a captive layer, a scale you cannot reach, a requirement you cannot meet. The bill comes due eventually. The mock migration just handed me an early copy.
I went looking because I built a scenario where someone asked me to move. What I found was that almost everything in the application was ceded, not decided — and the two things I did decide, the model runtime and identity, I can point to and defend. The rest drifted in, one convenient default at a time, starting with a single choice to put the platform estate on Firestore. I did not mean to cede the pipeline, or 2C, or the retrieval strategy. I meant to cede the model and the identity. Now I know the difference.
Knowing the difference is the whole point of the read. It does not tell you to avoid lock-in. It tells you which locks you backed into by accident, so you can decide which ones you actually meant.
That sets up the next move. This piece was detection — finding the ceded authority and naming what drifted versus what I decided. In part two I go back through the same application and place the authority on purpose: take each cession the assessment surfaced and decide it deliberately, the version of this work I wish I had done before I ever wrote a line of the Virtual CTO Advisor.
Share This Story, Choose Your Platform!

Keith Townsend is a seasoned technology leader and Founder of The Advisor Bench, specializing in IT infrastructure, cloud technologies, and AI. With expertise spanning cloud, virtualization, networking, and storage, Keith has been a trusted partner in transforming IT operations across industries, including pharmaceuticals, manufacturing, government, software, and financial services.
Keith’s career highlights include leading global initiatives to consolidate multiple data centers, unify disparate IT operations, and modernize mission-critical platforms for “three-letter” federal agencies. His ability to align complex technology solutions with business objectives has made him a sought-after advisor for organizations navigating digital transformation.
A recognized voice in the industry, Keith combines his deep infrastructure knowledge with AI expertise to help enterprises integrate machine learning and AI-driven solutions into their IT strategies. His leadership has extended to designing scalable architectures that support advanced analytics and automation, empowering businesses to unlock new efficiencies and capabilities.
Whether guiding data center modernization, deploying AI solutions, or advising on cloud strategies, Keith brings a unique blend of technical depth and strategic insight to every project.




