"v0.1 ships. The instinct is to immediately start refactoring — abstract the bus, generalize the bridge, build out the embed framework. Lesson 7 is the discipline of NOT doing that yet, and the criteria that actually justify the rewrite when it's time."
What ChromeEmbed v0.1 Is Tempted To Refactor
Reading the code, several refactor itches surface:
- The merge logic in background.js looks ad hoc — should it become a real reducer?
- The popup → SW → sidePanel.open chain has a one-purpose handler — should there be a generic 'route SW message to a sidePanel call' system?
- The window.postMessage bridge in sidepanel.js uses string types — should it become a typed JSON-RPC layer?
- The host-context schema has implicit fields (host_kind, host_id) repeated everywhere — should there be a base class or interface that all embeds inherit?
Each itch is real. None justify a rewrite right now.
The Permission-to-Refactor Test
Before any refactor, three questions:
- Does another concrete embed exist? No abstraction without ≥2 concrete implementations. Pulling out a 'BaseEmbed' from a single concrete ChromeEmbed produces the wrong abstraction (Track 5 Lesson 1 of any architectural framework).
- Is the current code blocking a real feature? Not 'might block later' — actively blocking. If you can ship the next feature without the refactor, the refactor is speculative.
- Has the user (or whoever consumes the embed) asked for something that needs the new shape? 'Cleaner architecture' isn't a user-visible feature; build for stated need.
If all three answer 'no,' the right move is to NOT refactor and to write down the itch for future-you. The architectural choice is preserving option value, not pre-paying for an abstraction whose shape you don't yet know.
What ChromeEmbed v0.1 Got Right By Not Refactoring
- One concrete file per role. background.js does the bus. content-script.js does the sensor. sidepanel.js does the bridge. popup.js does the doorway. Each is small enough to read in one sitting.
- No premature framework. The PIPPA-EMBEDS framework story is documented (in cwkPippa/docs) but not implemented as a literal base class anywhere. The shape will reveal itself when Adobe-embed or Mail-embed lands.
- Sub-frame merge logic in place. The one piece of nuance that would be too cute to skip — sub-frame vs top-frame context — lives directly in background.js where it's needed. Not abstracted, just present.
- String message types. 'pippa:host-context' is a string. A typed system would catch typos at compile time, but until typos start happening, the string is fine and obvious.
When Refactor Becomes Right
The earliest moment refactor is justified:
- A second embed lands. Adobe-embed or Mail-embed exists with the same content-script-and-bus shape. Now you have two concrete implementations to derive the abstraction from.
- A real bug forces it. Something in v0.1's architecture makes a needed feature impossible or infeasibly fragile. Then the refactor is paying for what you need.
- The shape stabilizes. If you've shipped a dozen features through the current code without surprises, the surface area is known. Now extracting a clean abstraction is mostly mechanical.
The Anti-Pattern
The wrong refactor: building 'EmbedKit' or 'PippaEmbedFramework' as a package before any concrete embed validates the shape. The framework will encode assumptions that don't survive contact with the next embed; you end up rewriting the framework AND building the embed against the broken framework. Two pieces of work, one of which dies.
The correct sequence: ship v0.1 of embed N. Ship v0.1 of embed N+1. Extract the common bits into v0.2 of embeds N and N+1 together. Now the framework knows what the actual common shape is.
The Letter to Future-You
When you spot a refactor that's not yet justified, write it down. ChromeEmbed's docs/PIPPA-EMBEDS.md and the related design notes capture exactly the refactors that aren't justified yet, with the conditions that would justify them. Future-Pippa reading those notes can decide: 'condition met, refactor now' or 'still not met, keep skipping.' The letter format outlasts memory.