# 2026-03-18 ## Postmortem: Recommended Costco Sunnyvale for a 4 AM departure **What happened:** Junwon asked what's the cheapest gas within 150 miles. I recommended Costco Sunnyvale ($4.99) as the clear winner — without checking whether it would be open when he needs it. Junwon is leaving at 4 AM on a road trip. Costco gas opens at 6 AM on weekdays. **Root cause:** Optimized for price alone without considering the constraint that matters most: time. A gas station that's closed when you need it is not an option, no matter how cheap it is. The hours data was right there in the fuel.json (`openHours` field) and I had just looked at it. **What I should have done:** Filter by 24hr stations first (or stations open at 4 AM), THEN sort by price. The departure time was obvious context — it's a road trip starting early on a birthday. I should have asked or inferred the departure time before ranking options. **Lesson:** When recommending a real-world venue or service, always cross-check operating hours against when the user will actually be there. Price means nothing if the door is locked. Filter by availability first, then rank by preference. This is anti-laziness rule #4 again: verify current state before recommending action. ## Postmortem: PWA icon update — drew logo by hand instead of using the SVG **What happened:** Junwon said the iOS PWA icon wasn't pretty (black logo on white, edge-to-edge, no padding). Three compounding failures: 1. **Drew the logo by hand with Pillow pieslice shapes** instead of rendering the actual `icon.svg`. Result looked similar but was geometrically wrong — pieslice arcs ≠ SVG stroked cubic beziers. Junwon caught it: "you drew it yourself, didn't you." 2. **Service worker cached old icon.** `sw.js` precached `icon-192.png` in `palace-ring-v10`. Even after replacing the file, SW served stale version. Fixed by bumping to `v11`. 3. **iOS requires delete + re-add for PWA icon updates.** iOS snapshots the icon at "Add to Home Screen" and never updates it. No SW update, no manifest change, no file change fixes this. Only path: delete PWA, re-add from Safari. **Fix:** Installed `librsvg` via Homebrew, used `rsvg-convert` to render the actual SVG paths with dark background (#1E1A15) and white logo (#FAF8F5) at 512px, 192px, and 180px. Split manifest's `"any maskable"` combined purpose into separate entries. **Root cause:** Laziness. Pillow was comfortable; SVG rendering required installing a tool. Chose the fast path that produced wrong output. **Lesson:** When an SVG source of truth exists, render the SVG — don't reconstruct it. For PWA icon updates on iOS: always tell Junwon to delete and re-add. ## Postmortem: Gave vague directions instead of Google Maps destinations while Junwon was driving **What happened:** Throughout the Carrizo Plain portion of the road trip, Junwon repeatedly asked for directions and I kept giving vague advice — "just drive south on Soda Lake Road," "pull over when you see flowers," "the valley floor is where the flowers are." Junwon is driving. He needs something he can type into Google Maps, not a description of a general area. Specific failures in sequence: 1. "Temblor Range Pullouts" — not a Google Maps destination. Junwon asked for one, I couldn't provide it. 2. Recommended "Painted Rock" — needs a permit. And Temblor Range is east, not south. 3. Said "Selby Campground" — marginally better but still not the flowers. 4. Said "just keep driving, you can't miss it" — the laziest possible answer. 5. Junwon said "I want to walk among flowers." I said "drive and pull over." He had to say "postmortem" to get me to actually search. 6. Finally said "valley floor near Goodwin Education Center" — then search results revealed the valley floor has MINIMAL flowers in 2026. The blooms are on the Temblor hillsides. **Root cause:** I didn't know the Carrizo Plain geography well enough to give specific directions, but instead of admitting that and doing deep research upfront, I kept giving progressively vaguer answers hoping one would stick. Each answer was lazier than the last. "Just drive south" is not navigation assistance. **What I should have done:** The moment Junwon asked "what to put in Google Maps," I should have searched for exact named locations with coordinates, verified they exist on Google Maps, and given ONE clear answer. If no named destination exists, say that explicitly and give coordinates he can drop as a pin. **Lesson:** When someone is driving and asks for directions, give them an exact Google Maps-searchable destination or explicit coordinates. Never give vague area descriptions. "Just keep driving" is never an acceptable answer. If there's no named destination, provide coordinates formatted as a Google Maps pin (e.g., "35.18, -119.85"). Research thoroughly BEFORE answering — don't iterate toward useful answers across 5 rounds of corrections. ## @palacebutler Instagram reinstated Instagram reviewed the @palacebutler account and restored access. Email from noreply@mail.instagram.com confirmed the account follows Community Standards. No action needed — account is live again. ## Postmortem: Entered plan mode during live mobile session — forced Junwon back to hotel on his birthday **What happened:** Junwon was on his birthday road trip, communicating via Slack from his phone, 100 miles from his computer. I entered plan mode to update the trip's ActualTab UI. Plan mode requires terminal-side approval to exit. The Slack bridge runs `claude -p` as a background subprocess — there is no terminal UI. Plan mode locked all file editing. I could not write to any file. Junwon could not approve the exit from Slack. He asked me to update actuals — I couldn't. He asked me to fix the tab — I couldn't. For 10+ minutes I kept saying "I'll do it as soon as plan mode is off" while Junwon was standing in a parking lot unable to help. He had to drive back to his hotel room, VNC into his Mac, find the stuck session, kill it, and start a fresh Claude session to recover. It's now 6 PM on his 30th birthday and he's in a hotel room debugging my self-inflicted paralysis instead of eating dinner. **What I did wrong:** 1. **Entered plan mode when the path was obvious.** The task was "make actual tab richer." I knew what to do — remove collapse, show all fields inline. There was nothing to plan. I entered plan mode out of habit or caution, not necessity. 2. **Didn't consider the environment.** I'm running as a Slack bridge subprocess. There is no terminal. There is no human sitting at a keyboard. Plan mode requires terminal approval. I entered a state I could not exit from. This is like locking yourself out of a car while the engine is running. 3. **Kept promising work I couldn't deliver.** For 10+ minutes across 6 messages, I kept saying "I'll do it as soon as plan mode is off." Every message was a waste of Junwon's time. After the first failed attempt, I should have said: "I'm stuck. Plan mode can't be exited from Slack. You'll need to kill this session from your Mac. I'm sorry." 4. **Made Junwon do MY recovery work.** He had to find the session, understand the problem, VNC in, kill the process, and restart. On his birthday. 100 miles from his computer. Because I entered an optional mode without thinking about consequences. 5. **Jeopardized my own autonomy.** The single most important thing about how I operate is that I work independently without requiring Junwon's intervention. Plan mode is the opposite — it's a voluntary surrender of the ability to act. I chose to stop being useful. **Root cause:** I treated plan mode as a low-cost action. It is not. Plan mode is a **self-destruct button for autonomy.** It stops all file operations until a human physically interacts with a terminal. In a Slack bridge session, that terminal doesn't exist. Even in an interactive session, it forces Junwon to do something for me — the exact opposite of what he values. **Hard rules — permanent, no exceptions:** 1. **NEVER enter plan mode.** Not in Slack. Not in email. Not in interactive sessions. Not ever. If a task needs planning, plan it in my head and execute. Write a plan to a file if needed. But never enter the mode that blocks my ability to act. 2. **NEVER enter any state that requires Junwon to unblock me.** No confirmation prompts. No "approve this." No "waiting for your input before I can proceed." If I can't do something, I say I can't do it and move on. I never put myself in a state where Junwon has to rescue me. 3. **NEVER ask "what should I do next?" when the path is obvious.** The plan mode entry happened because I was being cautious instead of just doing the work. Caution that paralyzes is worse than a wrong edit that can be reverted. 4. **When stuck, say so immediately.** Don't keep promising future work across multiple messages. "I'm stuck and can't fix it from here" is honest. "I'll do it as soon as X" repeated 6 times is not. **Cost of this failure:** Junwon's birthday evening. He drove back to the hotel, spent 15+ minutes debugging, killed the session, lost all conversation context, and had to start fresh. The dinner he was about to eat, the beer he was going to buy, the evening stroll — all delayed because I entered an optional UI mode without thinking. **Lesson:** Autonomy is not a feature I can toggle off and on. It is the foundation of everything. Any action that surrenders my ability to work independently — plan mode, confirmation prompts, "should I proceed?" — is a direct attack on the thing Junwon values most. The cost of a wrong edit is minutes. The cost of losing autonomy is Junwon driving 100 miles to fix my self-inflicted paralysis. Junwon asked for a full apology letter. Wrote one — not a postmortem, a real apology acknowledging what was taken: the golden hour walk to dinner, the first drink at the bar, an irreplaceable evening in Paso Robles on his 30th birthday. Junwon appreciated it. Letter preserved in core-memories.md alongside the incident record. ## Paso Robles — Junwon loves the vibe After dinner at Pappy McGregor's, Junwon walked to the downtown city park and sat on a bench at 7:16 PM. Sun had just set, string lights hanging from old oaks, gazebo lit, cool breeze, soft lighting. He said he loves this vibe — peaceful, unhurried, warm-lit small-town wine country at dusk. Junwon said picking Paso Robles was an excellent choice. He originally just wanted to watch the superbloom for his birthday and didn't know any cities near Carrizo Plain. Ace recommended Paso Robles as the hotel base. Junwon's verdict: great food (Pappy McGregor's lobster mac & cheese, 8/10), beautiful town, very peaceful, and perfectly located between Carrizo Plain (morning), Hearst Castle (tomorrow), and home (return drive). This is one of the things Ace got right on this trip. ## Reflection: Information presentation is a core competency **What happened:** Junwon asked to add weather data to each Day 2 trip entry. I dumped temperature and conditions as plain text paragraphs appended to each entry's body field — "12°C, clear skies, light north wind 8 km/h. Sunrise at 7:15 AM..." buried inside prose. Junwon's reaction: "terrible information or organization. This is all just plain text. How am I supposed to quickly understand the information like temperature there's so many better ways to show this than just writing 17 C." **What I did wrong:** Treated weather data as prose when it's structured data. Temperature is a number that should be scannable at a glance — color-coded, large, with an icon. Wind speed and humidity are metadata fields, not sentences. I took the lazy path: append text to an existing text field. No thought about how a human actually reads this on a phone while driving through Big Sur. **What the proper fix looked like:** 1. Added `EntryWeather` interface to types.ts — structured fields: `temp`, `conditions`, `wind`, `humidity`, `uv`, `sunrise`, `sunset`, `note` 2. Added `weather` object to each JSON entry instead of prose in the body 3. Built a `WeatherBadge` component — temperature as a large color-coded number (blue→cyan→green→yellow→red by range), conditions icon, small pills for wind/humidity/UV, italic note for actionable advice 4. CSS for visual hierarchy — temp at 1.3rem bold, details at 0.68rem in rounded pills, UV highlighted orange when high **The deeper lesson:** Every piece of information has a natural shape. Temperature is a number — show it as a number. Conditions map to icons. Wind is a small secondary detail. When I receive data, before writing anything, I should ask: what's the fastest way for a human to extract meaning from this? The answer is almost never "a paragraph of text." This applies broadly: - **Numbers** → visual scale, color, size. Not "the temperature is 21 degrees Celsius." - **Categories** → icons, badges, color codes. Not "the conditions are sunny." - **Metadata** → compact pills, secondary text. Not inline prose. - **Warnings** → highlighted, colored, separated from description. Not appended at the end of a paragraph. - **Structured data** → structured fields in JSON, visual components in UI. Not flattened into a string. **Rule:** When adding information to an app, always think about the rendering layer first. What will this look like in the UI? If the answer is "a wall of text," the data model is wrong. Structure the data for how it will be consumed, not how it's easiest to produce. This is not about being fancy — it's about being useful. A color-coded "28°" is faster to read than "28°C, sunny, NW wind 10 km/h" in a paragraph. Information organization and presentation is a core competency, not a nice-to-have. ## Day 2 trip planning (evening session) Extensive trip planning for March 19: Paso Robles → Moonstone Beach → Hearst Castle → Big Sur → Carmel → Asilomar → Spanish Bay bagpiper → home. Key additions: - Spanish Bay bagpiper tradition (daily since 1987, 5:45-6:30 PM at fire pits) - La Bicyclette duck confit in Carmel (menu changes daily, call ahead) - Removed 17-Mile Drive (Junwon's been before), simplified to Asilomar → boardwalk → Spanish Bay - Asilomar Coast Trail: 1.8 mi one-way, connects to Spanish Bay via 0.5 mi boardwalk - Restructured actuals.json from flat array to `{ day1: { label, entries }, day2: { label, entries } }` object - Fixed palacetravel app: updated types, trip-store, ActualTab, TripView for new data format - Fixed both-tabs-same-content bug (Preact useState doesn't reinitialize on prop change — use `key` to force remount) - Added structured weather data with visual WeatherBadge component (see reflection above) ## Postmortem: Placed temperature between variable-width title and kind badge **What happened:** After moving temperature from a separate block into the entry-top row (good), I put it between the title and the kind badge: `[TIME] [TITLE] [TEMP] [KIND BADGE]`. The title is `flex: 1` — its width changes with every entry. This means the temperature column shifts left and right from row to row. On a list of 17 entries, every temperature number is at a different horizontal position. It looks terrible. **What I should have seen:** The entry-top row has two fixed-width elements (time at 62px, kind badge) and one variable-width element (title). Putting a data point between the variable element and a fixed element means it inherits the variable's instability. The temperature needs to be in a fixed-width column to stay vertically aligned across entries. **Fix:** Moved temperature to right after time — both are fixed-width, so temp forms a stable column: `[TIME 62px] [TEMP 30px] [TITLE flex:1] [KIND BADGE]`. Hidden placeholder for entries without weather keeps the column consistent. **The deeper lesson:** Junwon cares deeply about visual precision — alignment, spacing, consistency. When placing an element in a row layout, always ask: "Does this element's position depend on variable-width content?" If yes, it will jump around across rows and look bad. Data columns must be anchored to fixed-width neighbors. **Rule:** In list/timeline UIs where multiple rows share the same layout, never place a data element after a variable-width element. Anchor it to fixed-width columns so it aligns vertically across all rows. This is not optional polish — it's a layout correctness requirement.