Skip to content

Commit a24778b

Browse files
committed
docs: rename Portfolio to Umbrella in cloud protocol
1 parent 907a88d commit a24778b

File tree

1 file changed

+144
-31
lines changed

1 file changed

+144
-31
lines changed

jekyll/_posts/2025-11-29-vibe-coding-cloud-protocol.md

Lines changed: 144 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ So I collapsed the complexity. I realized that for us—the builders, the hacker
4949

5050
We don't need a "Finance View" and an "Ops View." We need a **Unified Tree**. A single vertical line that connects the credit card to the code.
5151

52-
(In earlier posts, I called these top-level buckets **Umbrellas**. In this post, I’ll call them **Portfolios**. Same idea, slightly nicer word.)
53-
5452
---
5553

5654
## 2. The Blueprint: One Hierarchy to Rule Them All
@@ -71,9 +69,9 @@ graph LR
7169
Root["PreAngel LLC<br/>(Agreement + Tenant)"]:::l1
7270
end
7371
74-
subgraph Level2 ["Level 2: Portfolio"]
72+
subgraph Level2 ["Level 2: Umbrella"]
7573
direction TB
76-
Umb1["PreAngel<br/>(Production Portfolio)"]:::l2
74+
Umb1["PreAngel<br/>(Production Umbrella)"]:::l2
7775
Umb2["Ship.Fail<br/>(Experiments)"]:::l2
7876
end
7977
@@ -107,7 +105,7 @@ graph LR
107105
### The 5 Levels of Sanity
108106

109107
1. **Company:** Who pays? (PreAngel LLC)
110-
2. **Portfolio:** What is the *context*? (Ship.Fail for experiments, PreAngel for serious products)
108+
2. **Umbrella:** What is the *context*? (Ship.Fail for experiments, PreAngel for serious products)
111109
3. **Project:** What is the *workload*? (Zixia, ReMic, Thoth)
112110
4. **Resource Group:** The container (Stage + Component).
113111
* **Stage:** `dev` (continuous deployment) vs `prod` (hand-picked versions).
@@ -124,12 +122,12 @@ I created a "Translation Layer" to map their complex terms to my simple reality.
124122
| Level | My Name | What it means to ME | Azure Term (Reference Only) |
125123
| ----- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
126124
| **1** | **Company** | My company (the root that owns the credit card and the tenant). | Billing account + tenant |
127-
| **2** | **Portfolio** | A context bucket: PreAngel (production), Ship.Fail (experiments), ToBeMigrated (legacy parking lot). | Invoice section |
125+
| **2** | **Umbrella** | A context bucket: PreAngel (production), Ship.Fail (experiments), ToBeMigrated (legacy parking lot). | Invoice section |
128126
| **3** | **Project** | A named workload like Zixia, Thoth, ReMic. In PreAngel: maps 1:1 to an Azure (subscription). In Ship.Fail: implemented as a family of Resource Groups inside a shared lab Azure (subscription). | Azure subscription (PreAngel) / Resource Group family in a shared Azure subscription (Ship.Fail) |
129127
| **4** | **Resource Group** | A logical container for a specific Stage (`dev`/`prod`) and Component (`web`/`api`). | Resource group |
130128
| **5** | **Resource** | The actual thing: VM, DB, storage account, function, key vault, etc. | Resource |
131129

132-
**The Golden Rule:** After this table, I almost never say "subscription" out loud. I speak in **Portfolios** and **Projects**, and only mention Azure terms in parentheses when I really need to.
130+
**The Golden Rule:** After this table, I almost never say "subscription" out loud. I speak in **Umbrellas** and **Projects**, and only mention Azure terms in parentheses when I really need to.
133131

134132
### Stage Is Virtual (But Critical)
135133

@@ -146,16 +144,16 @@ Here’s the twist that makes everything click:
146144

147145
The **Unified Tree** is always the same in my head:
148146

149-
> Company → Portfolio → Project → Resource Group (Stage + Component) → Resource
147+
> Company → Umbrella → Project → Resource Group (Stage + Component) → Resource
150148
151-
But it is **implemented differently** for my two main portfolios:
149+
But it is **implemented differently** for my two main umbrellas:
152150

153-
* **PreAngel (Production Portfolio)**
151+
* **PreAngel (Production Umbrella)**
154152

155153
* **Project = Azure (subscription).**
156154
* Each serious product (like Zixia) gets its own Project at the subscription level.
157155
* Inside that, I create Resource Groups for `dev` and `prod` plus components (`web`, `api`, `data`, ...).
158-
* **Ship.Fail (Experiment Portfolio)**
156+
* **Ship.Fail (Experiment Umbrella)**
159157

160158
* Everything is **leveled down by one notch** to keep life simple.
161159
* Ship.Fail uses **one shared lab Azure (subscription)**.
@@ -165,13 +163,13 @@ You can visualize it like this:
165163

166164
```text
167165
Production
168-
Company → Portfolio (PreAngel) → Project → Resource Group (w/Stage) → Resource
166+
Company → Umbrella (PreAngel) → Project → Resource Group (w/Stage) → Resource
169167
^
170168
|
171169
Azure (subscription)
172170
173171
Lab: Hackathon Ideas / MVPs
174-
Company → Portfolio (ShipFail) → [Project → Resource Group (w/Stage)] → Resource
172+
Company → Umbrella (ShipFail) → [Project → Resource Group (w/Stage)] → Resource
175173
^
176174
|
177175
Azure (subscription)
@@ -190,7 +188,7 @@ When a Ship.Fail project becomes a “real” product:
190188
* When it “graduates” to PreAngel, I **move it up one layer**:
191189

192190
* I create a new production Project at the subscription layer (e.g., `prj-preangel-remic` as an Azure subscription name), and
193-
* I recreate its Resource Groups following the same pattern but under the PreAngel portfolio (e.g., `rg-preangel-remic-dev-web`, `rg-preangel-remic-prod-web`).
191+
* I recreate its Resource Groups following the same pattern but under the PreAngel umbrella (e.g., `rg-preangel-remic-dev-web`, `rg-preangel-remic-prod-web`).
194192

195193
The names barely change—mostly `shipfail``preangel`—but the Project moves from “lab” mode to “production” mode.
196194

@@ -349,7 +347,7 @@ Here is what my cloud looks like in the Ship.Fail lab subscription:
349347

350348
```text
351349
Company: PreAngel LLC
352-
└─ Portfolio: ShipFail
350+
└─ Umbrella: ShipFail
353351
└─ Project: ReMic (conceptually: prj-shipfail-remic)
354352
├─ Resource Group: rg-shipfail-remic-dev-web
355353
│ ├─ vm-shipfail-remic-dev-web
@@ -366,7 +364,7 @@ All of these live inside the same Ship.Fail lab Azure (subscription), reuse the
366364

367365
Future-me can open any of those names in the cloud console and instantly know:
368366

369-
1. **Portfolio:** It's a Ship.Fail experiment.
367+
1. **Umbrella:** It's a Ship.Fail experiment.
370368
2. **Project:** It's for ReMic.
371369
3. **Stage:** It's `dev` (continuous deployment) or `prod` (hand-picked versions).
372370
4. **Component:** It's the `web` or `api` layer.
@@ -377,14 +375,14 @@ Now suppose ReMic proves itself and deserves to become a serious product.
377375

378376
I don’t throw away the tree; I simply **move it up one level**:
379377

380-
* I create a new production Project under the PreAngel portfolio, implemented as its own Azure (subscription):
378+
* I create a new production Project under the PreAngel umbrella, implemented as its own Azure (subscription):
381379

382380
* `prj-preangel-remic`
383381
* Inside that subscription, I recreate the Resource Groups with the same pattern:
384382

385383
```text
386384
Company: PreAngel LLC
387-
└─ Portfolio: PreAngel
385+
└─ Umbrella: PreAngel
388386
└─ Project: prj-preangel-remic
389387
├─ Resource Group: rg-preangel-remic-dev-web
390388
├─ Resource Group: rg-preangel-remic-prod-web
@@ -401,15 +399,130 @@ The mental model is the same. The only changes are:
401399
* `Portfolio` value: from `ShipFail``PreAngel`.
402400
* Physical level where the Project lives: from Resource Group family inside a shared subscription → its own subscription.
403401

402+
* `Umbrella` value: from `ShipFail``PreAngel`.
403+
* Physical level where the Project lives: from Resource Group family inside a shared subscription → its own subscription.
404+
404405
That’s how graduation works in this protocol.
405406

407+
---
408+
409+
## 4. The Naming Playbook: Rules for the Road
410+
411+
A naming convention is useless if you have to look it up every time. It needs to be intuitive. Here is the **Ship.Fail Protocol**.
412+
413+
### Rule #1: The Umbrella
414+
415+
I have exactly three Umbrellas (contexts). No more, no less.
416+
417+
* `umb-preangel` (Real products making money)
418+
* `umb-shipfail` (Hackathons, MVPs, crazy ideas)
419+
* `umb-tobemigrated` (The "Box of Shame" for old stuff)
420+
421+
### Rule #2: The Project
422+
423+
Projects are the atomic unit in my head. They are named explicitly:
424+
425+
```text
426+
prj-<umbrella>-<project>
427+
```
428+
429+
Examples:
430+
431+
* `prj-preangel-zixia`
432+
* `prj-shipfail-thoth`
433+
* `prj-shipfail-remic`
434+
435+
How this plays out in practice:
436+
437+
* In **PreAngel**, `prj-preangel-zixia` is both:
438+
439+
* the conceptual Project name, and
440+
* the name I give to its dedicated Azure (subscription).
441+
* In **Ship.Fail**, `prj-shipfail-remic` is still the conceptual Project name, but:
442+
443+
* all Ship.Fail Projects share a single lab Azure (subscription), and
444+
* the Project is implemented as a **family of Resource Groups and tags** with the `shipfail-remic` pattern.
445+
446+
**Why this works:** When I see `prj-shipfail-thoth`, I know instantly: *This is an experiment (Ship.Fail) called Thoth.* Whether it currently lives as its own subscription (PreAngel style) or as Resource Groups inside the lab subscription (Ship.Fail style) is an implementation detail I can always look up—but the name and tags tell the story.
447+
448+
### Rule #3: The Resource Group (The Backbone)
449+
450+
This is where the magic happens. The Resource Group name encodes the entire lineage of the resource.
451+
452+
```text
453+
rg-<umbrella>-<project>-<stage>-<component?>
454+
```
455+
456+
Examples:
457+
458+
* `rg-shipfail-remic-dev-web`
459+
* `rg-preangel-zixia-prod-data`
460+
461+
Under Ship.Fail, this is also how Projects show up structurally:
462+
463+
* `rg-shipfail-remic-dev-web`, `rg-shipfail-remic-dev-api`, `rg-shipfail-remic-prod-web`, ...
464+
* All of them live inside the **same Ship.Fail lab subscription**, but their names and tags still encode Umbrella, Project, Stage, and Component.
465+
466+
**The "3-Second Rule":** If I can't tell you exactly what a Resource Group contains and who pays for it within 3 seconds of reading the name, **it is a bad name.**
467+
468+
### Rule #4: The Resource (Type-First)
469+
470+
I use type‑first naming. Start with the resource type abbreviation, then echo the hierarchy.
471+
472+
```text
473+
<shorttype>-<umbrella>-<project>-<stage>-<component?>
474+
```
475+
476+
Examples:
477+
478+
* `vm-shipfail-remic-dev-web` (A VM)
479+
* `st-shipfail-thoth-dev-data` (A Storage Account)
480+
* `fn-preangel-zixia-prod-web` (A Function App)
481+
* `db-preangel-zixia-prod-api` (A Database)
482+
483+
Type-first gives me a nice property when I sort by name:
484+
485+
* all `vm-*` resources group together,
486+
* all `db-*` resources group together,
487+
* and my eyes can skim quickly.
488+
489+
### A Before → After Rename Example
490+
491+
Here’s how this looks in practice on a messy real-world example.
492+
493+
**Before:**
494+
495+
* Resource Group: `Default-Web-WestUS`
496+
* Storage Account: `mystorage123`
497+
498+
Three months later, I have *no idea* what either of those are.
499+
500+
**After:**
501+
502+
```text
503+
Resource Group: rg-shipfail-remic-dev-web
504+
Storage Account: st-shipfail-remic-dev-web
505+
Tags:
506+
Umbrella = ShipFail
507+
Project = ReMic
508+
Stage = dev
509+
Component = web
510+
```
511+
512+
Now the same pair of resources tells me, at a glance:
513+
514+
* this is part of the **ReMic** Project,
515+
* under the **Ship.Fail** umbrella,
516+
* in the **dev** stage,
517+
* in the **web** component.
518+
406519
### 6.3 Zixia as a PreAngel Project (Always Production-First)
407520

408-
The **PreAngel** portfolio is where my “serious” products live. Zixia is one of them.
521+
The **PreAngel** umbrella is where my “serious” products live. Zixia is one of them.
409522

410523
```text
411524
Company: PreAngel LLC
412-
└─ Portfolio: PreAngel
525+
└─ Umbrella: PreAngel
413526
└─ Project: prj-preangel-zixia
414527
├─ Resource Group: rg-preangel-zixia-dev-web
415528
│ └─ fn-preangel-zixia-dev-web
@@ -420,7 +533,7 @@ Company: PreAngel LLC
420533
Its tags might look like this:
421534

422535
```text
423-
Portfolio = PreAngel
536+
Umbrella = PreAngel
424537
Project = Zixia
425538
Stage = dev / prod
426539
Component = web
@@ -439,7 +552,7 @@ I stripped my tagging strategy down to the bare essentials. I removed the `Org`
439552
**The Essential Tag Set:**
440553

441554
```text
442-
Portfolio = PreAngel | ShipFail | ToBeMigrated
555+
Umbrella = PreAngel | ShipFail | ToBeMigrated
443556
Project = Zixia | Thoth | ReMic | ...
444557
Stage = dev | prod
445558
Component = web | api | data | tools | ...
@@ -448,7 +561,7 @@ Component = web | api | data | tools | ...
448561
**Example:** A production database for Zixia.
449562

450563
* **Name:** `db-preangel-zixia-prod-api`
451-
* **Tags:** `Portfolio=PreAngel`, `Project=Zixia`, `Stage=prod`, `Component=api`
564+
* **Tags:** `Umbrella=PreAngel`, `Project=Zixia`, `Stage=prod`, `Component=api`
452565

453566
Now, when I want to know *"How much am I spending on all my `dev` stages combined?"*, it is a single filter away.
454567

@@ -458,22 +571,22 @@ Now, when I want to know *"How much am I spending on all my `dev` stages combine
458571

459572
Ready to turn your graveyard into a machine? Here is the exact checklist I used. Steal it.
460573

461-
1. **Define Your Portfolios.**
574+
1. **Define Your Umbrellas.**
462575
Commit to 2–3 high-level contexts. (For me: `PreAngel`, `ShipFail`, `ToBeMigrated`.)
463576

464-
2. **Decide Implementation Per Portfolio.**
577+
2. **Decide Implementation Per Umbrella.**
465578

466-
* For your “serious” portfolio (like PreAngel), let each Project be its own Azure (subscription).
467-
* For your “lab” portfolio (like Ship.Fail), pick one shared lab Azure (subscription) and implement Projects as families of Resource Groups inside it.
579+
* For your “serious” umbrella (like PreAngel), let each Project be its own Azure (subscription).
580+
* For your “lab” umbrella (like Ship.Fail), pick one shared lab Azure (subscription) and implement Projects as families of Resource Groups inside it.
468581

469582
3. **Inventory Your Projects.**
470-
List every Project you care about today and give it a clear name: `prj-<portfolio>-<project>`.
583+
List every Project you care about today and give it a clear name: `prj-<umbrella>-<project>`.
471584

472585
4. **Create the Containers.**
473586
For each Project:
474587

475-
* In PreAngel-style portfolios: create or rename the Azure (subscription) accordingly, then create Resource Groups using the `rg-...` pattern.
476-
* In Ship.Fail-style portfolios: create Resource Groups directly in the lab subscription using the `rg-...` pattern.
588+
* In PreAngel-style umbrellas: create or rename the Azure (subscription) accordingly, then create Resource Groups using the `rg-...` pattern.
589+
* In Ship.Fail-style umbrellas: create Resource Groups directly in the lab subscription using the `rg-...` pattern.
477590

478591
5. **The Great Migration.**
479592
Move resources into their new homes. If something doesn’t obviously belong to a Project and Stage, that’s a red flag.
@@ -482,7 +595,7 @@ Ready to turn your graveyard into a machine? Here is the exact checklist I used.
482595
If you find a resource that doesn't fit into your new tree... **delete it.** If you can't name it, you don't need it.
483596

484597
7. **Tag Everything.**
485-
No exceptions. Portfolio, Project, Stage, Component.
598+
No exceptions. Umbrella, Project, Stage, Component.
486599

487600
If you only have 30 minutes, pick **one** Project (for me, it was ReMic), apply the naming + tags + VNet model just to that, and stop. Even that small slice of clarity feels shockingly good.
488601

0 commit comments

Comments
 (0)