[object Object]

← back to Goodquestion Ai

auto-save: 2026-07-27T10:19:40 (9 files) — src/content/posts/2026-04-01-how-one-person-runs-150-autonomous-agents-on-a-single-80-dollar-server.md src/content/posts/2026-04-01-what-i-shipped-today-and-why-it-matters-automating-lead-time.md src/content/posts/2026-05-18-git-surgery-shrinking-a-repo-from-18gb-to-571mb.md src/content/posts/2026-06-10-cracking-a-fleet-of-broken-scrapers-in-one-day.md src/content/posts/2026-07-02-the-four-layer-bug-that-hid-behind-a-comment.md

36f03110f789347dbbc1f12f99e3729c81b2141a · 2026-07-27 10:19:46 -0700 · Steve Abrams

Files touched

Diff

commit 36f03110f789347dbbc1f12f99e3729c81b2141a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Jul 27 10:19:46 2026 -0700

    auto-save: 2026-07-27T10:19:40 (9 files) — src/content/posts/2026-04-01-how-one-person-runs-150-autonomous-agents-on-a-single-80-dollar-server.md src/content/posts/2026-04-01-what-i-shipped-today-and-why-it-matters-automating-lead-time.md src/content/posts/2026-05-18-git-surgery-shrinking-a-repo-from-18gb-to-571mb.md src/content/posts/2026-06-10-cracking-a-fleet-of-broken-scrapers-in-one-day.md src/content/posts/2026-07-02-the-four-layer-bug-that-hid-behind-a-comment.md
---
 ...tonomous-agents-on-a-single-80-dollar-server.md | 18 ++---
 ...oday-and-why-it-matters-automating-lead-time.md |  8 ++-
 ...-surgery-shrinking-a-repo-from-18gb-to-571mb.md | 10 +--
 ...acking-a-fleet-of-broken-scrapers-in-one-day.md |  4 +-
 ...the-four-layer-bug-that-hid-behind-a-comment.md |  4 +-
 ...review-that-caught-what-my-own-checks-missed.md | 10 +--
 src/data/projects.ts                               | 84 +++++++++++-----------
 src/pages/hire.astro                               | 42 +++++------
 src/pages/projects/index.astro                     |  4 +-
 9 files changed, 94 insertions(+), 90 deletions(-)

diff --git a/src/content/posts/2026-04-01-how-one-person-runs-150-autonomous-agents-on-a-single-80-dollar-server.md b/src/content/posts/2026-04-01-how-one-person-runs-150-autonomous-agents-on-a-single-80-dollar-server.md
index e7cb8c5..3caa408 100644
--- a/src/content/posts/2026-04-01-how-one-person-runs-150-autonomous-agents-on-a-single-80-dollar-server.md
+++ b/src/content/posts/2026-04-01-how-one-person-runs-150-autonomous-agents-on-a-single-80-dollar-server.md
@@ -22,7 +22,7 @@ I run 167 autonomous agents on a single server that costs $80 a month.
 
 Not on AWS Lambda. Not on Kubernetes. Not across a microservices mesh managed by a DevOps team of six. On one VPS. With one person operating it.
 
-This is not a toy project. These agents manage a live e-commerce operation with tens of thousands of products, ingest and normalize supplier catalogs nightly, sync data to Shopify, generate marketing content, monitor six production websites, and publish blog posts. They run 24/7. The server has been up for months.
+This is not a toy project. These agents manage a live e-commerce operation with a large product catalog, ingest and normalize supplier feeds nightly, sync data to a commerce platform, generate marketing content, monitor six production websites, and publish blog posts. They run 24/7. The server has been up for months.
 
 Here is exactly what the infrastructure looks like and why it works.
 
@@ -55,7 +55,7 @@ The critical insight: **most agents do not need to run continuously.** They wake
 
 One database. 351 tables. Every agent reads from and writes to the same PostgreSQL instance. No message queues. No event buses. No eventual consistency headaches.
 
-Each vendor gets its own catalog table. Each agent logs its runs. Each product flows through a pipeline of tables — raw scrape data, normalized specs, AI analysis results, Shopify sync status. The database is the coordination layer. If an agent needs to know what another agent did, it queries a table.
+Each supplier gets its own catalog table. Each agent logs its runs. Each product flows through a pipeline of tables — raw ingest data, normalized specs, AI analysis results, commerce-platform sync status. The database is the coordination layer. If an agent needs to know what another agent did, it queries a table.
 
 ### Claude Code for the AI Layer
 
@@ -75,14 +75,16 @@ This is not a chatbot factory. These are operational systems:
 
 **Catalog ingest agents** — dozens of agents pull structured product data from supplier feeds and catalog sources on a schedule. Each handles pagination, spec extraction, and image processing. When a source changes its data format, one agent breaks. The rest keep running.
 
-**Data pipeline agents** — Raw scrape data flows through normalization agents that clean SKUs, standardize color names, validate dimensions, and flag anomalies. A product without a width measurement never reaches the store. A product titled "Unknown" gets blocked automatically.
+**Data pipeline agents** — Raw ingest data flows through normalization agents that clean SKUs, standardize color names, validate dimensions, and flag anomalies. A product without a width measurement never reaches the store. A product titled "Unknown" gets blocked automatically.
 
-**Shopify sync agents** — Normalized data pushes to Shopify via GraphQL bulk operations. Product creation, variant management, metafield updates, image uploads. The Shopify Plus API handles 20 requests per second. Bulk operations process 50,000 products in under an hour.
+**Commerce sync agents** — Normalized data pushes to the commerce platform via bulk GraphQL operations. Product creation, variant management, metafield updates, image uploads. The platform's API handles 20 requests per second, and bulk operations move a large batch of products in under an hour.
 
 **Monitoring agents** — Process health, website uptime, error rates, port conflicts. Alerts go to Slack. Status reports run three times daily. When something crashes at 3 AM, I find out from a summary, not a page.
 
 **Content agents** — Blog generation, social media posting (Bluesky, TikTok, YouTube), marketing copy. This post was published by one of them.
 
+
+
 ## Why This Works on One Server
 
 The secret is not hardware. It is architecture.
@@ -107,10 +109,10 @@ Let me be precise about the economics:
 | PM2 (open source) | $0 |
 | Gemini API (vision analysis, batched) | ~$15-30 |
 | Claude Code (development + agent runtime) | Variable |
-| Shopify Plus (e-commerce platform) | ~$2,300 |
+| Commerce platform (hosted storefront) | Business expense |
 | **Total infrastructure** | **~$80** |
 
-The Shopify cost is a business expense, not an infrastructure cost. The AI API costs scale with usage but stay low because of batching and scheduling.
+The commerce-platform cost is a business expense, not an infrastructure cost. The AI API costs scale with usage but stay low because of batching and scheduling.
 
 Compare this to hiring. One junior developer in the US costs $6,000-8,000/month fully loaded. One. These 167 agents replace the output of 8-12 people across engineering, DevOps, QA, data, and content operations.
 
@@ -120,7 +122,7 @@ I am not going to pretend this is bulletproof. Things break regularly:
 
 - **Vendor websites change layouts.** A scraper that worked yesterday returns garbage today. Fix time: 15-30 minutes per scraper.
 - **PM2 processes zombie out.** Occasionally a process hangs instead of crashing. Monitoring catches it. A kill-and-restart script runs hourly.
-- **Disk fills up.** 400 GB sounds like a lot until you are storing product images for 60,000+ SKUs. Aggressive cleanup scripts run weekly.
+- **Disk fills up.** 400 GB sounds like a lot until you are storing product images for a large catalog. Aggressive cleanup scripts run weekly.
 - **Port conflicts.** 167 agents need 167 ports. I maintain a port registry. Collisions still happen when I forget to check it.
 
 None of these are catastrophic. All of them are fixable in minutes by one person. That is the point.
@@ -135,7 +137,7 @@ If you are a solo founder or a small team, here is the playbook:
 
 3. **Use cron for scheduling, not event systems.** A cron job that runs `pm2 start scraper-agent` at 2 AM is simpler and more debuggable than a Kafka consumer triggered by a CloudWatch event routed through an SNS topic.
 
-4. **Let AI write the boring parts.** Claude Code generates scraper templates, data normalization logic, and Shopify API integrations faster than you can type the spec. Your job is architecture and judgment calls, not boilerplate.
+4. **Let AI write the boring parts.** Claude Code generates scraper templates, data normalization logic, and commerce-platform API integrations faster than you can type the spec. Your job is architecture and judgment calls, not boilerplate.
 
 5. **Monitor aggressively.** The tradeoff of running everything on one server is that the server is a single point of failure. Slack alerts, health checks, and daily status reports are not optional. They are the only thing between you and a 3 AM surprise.
 
diff --git a/src/content/posts/2026-04-01-what-i-shipped-today-and-why-it-matters-automating-lead-time.md b/src/content/posts/2026-04-01-what-i-shipped-today-and-why-it-matters-automating-lead-time.md
index 973fe69..27f3c3c 100644
--- a/src/content/posts/2026-04-01-what-i-shipped-today-and-why-it-matters-automating-lead-time.md
+++ b/src/content/posts/2026-04-01-what-i-shipped-today-and-why-it-matters-automating-lead-time.md
@@ -1,5 +1,5 @@
 ---
-title: "What I Shipped Today and Why It Matters: Automating Lead Time Updates Across 40 Wallcovering Vendors"
+title: "What I Shipped Today and Why It Matters: Automating Lead-Time Updates Across Dozens of Suppliers"
 description: "A founder's daily log of building, automating, and shipping real systems."
 date: 2026-04-01
 tags: []
@@ -34,14 +34,16 @@ If you're running a business and not using AI to automate yet, you're leaving mo
 
 > "Quincy QA Agent Built & Deployed"
 
-The mission: **Automating Lead Time Updates Across 40 product Vendors**. Build it, ship it to production, and show other founders exactly how — no gatekeeping.
+The mission: **Automating Lead-Time Updates Across Dozens of Suppliers**. Build it, ship it to production, and show other founders exactly how — no gatekeeping.
 
-![Automating Lead Time Updates Across 40 product Vendors](/images/launch-meme.png)
+![Automating Lead-Time Updates Across Dozens of Suppliers](/images/launch-meme.png)
 
 ## How It Works
 
 Everything I build ships to production the same day. No staging. No waiting. If you're a business owner wondering whether AI can handle your operations — yes, it can. Follow the journey at [goodquestion.ai](https://goodquestion.ai).
 
+
+
 ### Today's Commits
 
 Shipped 13 commits:
diff --git a/src/content/posts/2026-05-18-git-surgery-shrinking-a-repo-from-18gb-to-571mb.md b/src/content/posts/2026-05-18-git-surgery-shrinking-a-repo-from-18gb-to-571mb.md
index c32d837..25563cc 100644
--- a/src/content/posts/2026-05-18-git-surgery-shrinking-a-repo-from-18gb-to-571mb.md
+++ b/src/content/posts/2026-05-18-git-surgery-shrinking-a-repo-from-18gb-to-571mb.md
@@ -11,17 +11,17 @@ My main commerce repo had a `.git` directory of 18 gigabytes. Not the working tr
 
 The working tree wasn't 18GB. The *history* was. Over 14 commits, a bunch of things had been committed that never should have been version-controlled:
 
-- Rendered room-setting images (regenerable — never belong in git)
-- Shopify backup dumps
+- Rendered product-mockup images (regenerable — never belong in git)
+- Storefront backup dumps
 - Debug output dumps
 - A 298 MB runtime database JSON
-- Whole directories of collection images and design assets
+- Whole directories of catalog images and design assets
 
 The problem with binary junk in git is that deleting it from the current commit does *nothing* to the repo size. Git keeps every version of every file forever. The 18GB is baked into the history. The only way to reclaim it is to rewrite the history itself.
 
 ## The Surgery
 
-I used `git filter-repo` to strip those paths out of all 14 commits — not just the latest, all of them. Then I updated `.gitignore` so the junk can never sneak back in, deleted the 18GB room-settings directory from disk entirely, and kept a full backup of the original `.git` in case anything went sideways.
+I used `git filter-repo` to strip those paths out of all 14 commits — not just the latest, all of them. Then I updated `.gitignore` so the junk can never sneak back in, deleted the 18GB rendered-image directory from disk entirely, and kept a full backup of the original `.git` in case anything went sideways.
 
 Result: `.git` went 18GB → 571MB, and the machine went from 23GB free to 44GB free. Since this repo has no remote configured, nothing was ever pushed anywhere — the rewrite was purely local and safe.
 
@@ -29,7 +29,7 @@ Result: `.git` went 18GB → 571MB, and the machine went from 23GB free to 44GB
 
 While I was in the history anyway, I audited for hardcoded credentials. It was bad:
 
-- A Shopify admin API token, hardcoded across **208 files**
+- A commerce-platform admin API token, hardcoded across **208 files**
 - A basic-auth password, hardcoded across **78 files**
 - A base64-encoded credential blob
 - Six stale `.backup` files sitting there holding plaintext secrets
diff --git a/src/content/posts/2026-06-10-cracking-a-fleet-of-broken-scrapers-in-one-day.md b/src/content/posts/2026-06-10-cracking-a-fleet-of-broken-scrapers-in-one-day.md
index 0203a13..c578bb6 100644
--- a/src/content/posts/2026-06-10-cracking-a-fleet-of-broken-scrapers-in-one-day.md
+++ b/src/content/posts/2026-06-10-cracking-a-fleet-of-broken-scrapers-in-one-day.md
@@ -11,7 +11,7 @@ I maintain scrapers for a large fleet of product vendors. Over time, a lot of th
 
 The fragile way to scrape a site is to render its HTML and dig through the DOM for the data you want. It works right up until the site changes its layout, at which point your carefully-tuned selectors point at nothing and the scraper silently returns zero products. Multiply that across 166 vendors on different platforms with different redesign schedules, and you have a fleet that's always partially broken.
 
-The durable insight: almost every modern storefront is a thin visual shell over a *structured data feed*. Shopify stores expose `products.json`. WooCommerce has a store API. Others carry the whole catalog in an in-page JSON blob or a search index. That feed changes far less often than the visual layout, and it hands you clean structured data instead of forcing you to parse markup.
+The durable insight: almost every modern storefront is a thin visual shell over a *structured data feed*. Most hosted commerce platforms expose a JSON product endpoint, WooCommerce has a store API, and others carry the whole catalog in an in-page JSON blob or a search index. That feed changes far less often than the visual layout, and it hands you clean structured data instead of forcing you to parse markup.
 
 ## The Work
 
@@ -19,7 +19,7 @@ The day was a systematic sweep across three tiers of scraping (new products, col
 
 - **A chokepoint fix healed ~20 vendors at once.** Several scrapers were returning flat product rows where the code expected a collections structure, so extraction got zero. Normalizing that at the single point where all vendors funnel through fixed all of them in one change.
 - **The blocked vendors got cracked without paid proxies.** Six vendors had been stuck behind anti-bot walls, previously requiring an expensive proxy service. One by one: one had its scraper pointed at the *wrong domain entirely* (a real find — it was scraping an unrelated site); others needed a native browser fingerprint to pass the wall; one exposed a clean in-page API. All six now work, and the paid proxy dependency is gone completely.
-- **The first full-fleet run pulled 2,227 genuinely-new products** from 135 vendors after deduping against what I already had — from a single command.
+- **The first full-fleet run pulled a big batch of genuinely-new products** from more than a hundred vendors after deduping against what I already had — from a single command.
 
 ## The Guardrail: Canary-First
 
diff --git a/src/content/posts/2026-07-02-the-four-layer-bug-that-hid-behind-a-comment.md b/src/content/posts/2026-07-02-the-four-layer-bug-that-hid-behind-a-comment.md
index 7752c42..43d2daf 100644
--- a/src/content/posts/2026-07-02-the-four-layer-bug-that-hid-behind-a-comment.md
+++ b/src/content/posts/2026-07-02-the-four-layer-bug-that-hid-behind-a-comment.md
@@ -2,7 +2,7 @@
 title: "The Four-Layer Bug That Hid Behind a Commented-Out Line"
 description: "A quantity stepper that snapped back to 1 was blocking real orders — and the fix required peeling back four separate bugs stacked on top of each other."
 date: 2026-07-02
-tags: ["debugging", "shopify", "frontend", "e-commerce", "founder-log"]
+tags: ["debugging", "storefront", "frontend", "e-commerce", "founder-log"]
 ---
 
 Some products in my store are supposed to be ordered in increments of two, starting at two — a minimum-order rule the manufacturer requires. The product page had a quantity stepper for exactly this. It didn't work. You'd set it to 4, and it would snap back to 1. And because it silently defaulted to 1, it was quietly *blocking every order larger than a single unit.* Here's how four separate bugs stacked up to cause it — and why I only found them by recording my own screen.
@@ -17,7 +17,7 @@ The breakthrough was giving up on reading code and instead **screen-recording th
 
 **Layer 1 — a JavaScript error killed initialization.** A function that drew the color swatches had a reference error (`c is not defined`). That error threw *before* the quantity-stepper setup code ran, so the stepper never initialized at all. One unrelated typo, and the whole feature was dead on arrival.
 
-**Layer 2 — the Sample variant poisoned the values.** Each product has a low-cost "Sample" variant with a min and step of 1. Selecting through the variants let the Sample's 1/1 values overwrite the roll's 2/2 values. So even when the stepper *did* initialize, it got contaminated with the wrong minimums.
+**Layer 2 — the Sample variant poisoned the values.** Each product has a low-cost "Sample" variant with a min and step of 1. Selecting through the variants let the Sample's 1/1 values overwrite the main variant's 2/2 values. So even when the stepper *did* initialize, it got contaminated with the wrong minimums.
 
 **Layer 3 — the increment button was commented out.** The actual `+`/`-` click handler had been *commented out* in a previous attempt. Why? Because someone (past me) was trying to hide the symptom of a deeper problem — the value kept snapping back, so disabling the buttons made the snap-back less visible. Classic: a workaround that masks a bug becomes a new bug.
 
diff --git a/src/content/posts/2026-07-26-the-review-that-caught-what-my-own-checks-missed.md b/src/content/posts/2026-07-26-the-review-that-caught-what-my-own-checks-missed.md
index de1ae91..8428320 100644
--- a/src/content/posts/2026-07-26-the-review-that-caught-what-my-own-checks-missed.md
+++ b/src/content/posts/2026-07-26-the-review-that-caught-what-my-own-checks-missed.md
@@ -1,11 +1,11 @@
 ---
 title: "The Review That Caught What My Own Checks Missed"
-description: "344 luxury products were displaying a $4.25 sample fee as their price — my activation checks passed, and an adversarial review caught it anyway."
+description: "A batch of quote-only products were displaying a small sample fee as their price — my activation checks passed, and an adversarial review caught it anyway."
 date: 2026-07-26
-tags: ["e-commerce", "code-review", "quality", "shopify", "founder-log"]
+tags: ["e-commerce", "code-review", "quality", "storefront", "founder-log"]
 ---
 
-I have a habit now that keeps saving me: after I build or activate something, I run it past an adversarial reviewer whose whole job is to *tear it apart*. Today that habit caught a defect that would have made 344 luxury, quote-only products display a **$4.25 sample fee as their price** on the live storefront — a defect my own activation checks had cheerfully waved through.
+I have a habit now that keeps saving me: after I build or activate something, I run it past an adversarial reviewer whose whole job is to *tear it apart*. Today that habit caught a defect that would have made a whole batch of premium, quote-only products display a **$4.25 sample fee as their price** on the live storefront — a defect my own activation checks had cheerfully waved through.
 
 ## The Setup
 
@@ -19,13 +19,13 @@ I'd activated a batch of these. My activation checks passed. Backend tags were c
 
 Then the adversarial review found the hole my checks missed. The products had the *backend* tag that marks them quote-only — but not the specific *storefront* tag that the theme actually reads to render the "contact for price" treatment instead of a price.
 
-So on the backend, everything was labeled correctly. On the front end, the theme didn't know these were quote-only, fell through to the default behavior, and displayed the $4.25 sample as the price. **344 products.** All live. All showing a swatch fee where a "contact us" should be.
+So on the backend, everything was labeled correctly. On the front end, the theme didn't know these were quote-only, fell through to the default behavior, and displayed the $4.25 sample as the price. **The whole batch.** All live. All showing a swatch fee where a "contact us" should be.
 
 My checks looked at the data model and said "correct." The customer's browser rendered the theme and said "$4.25." The gap between those two was exactly where the bug lived — and I only found it because something was actively trying to prove me wrong.
 
 ## The Fix
 
-First, *reproduce it* — I confirmed against the live theme that the price section only renders the quote-only treatment when the storefront tag is present, and that these products didn't have it. Then, additively (nothing destructive, fully reversible), I added the missing storefront tag to all 344. Now the pages correctly show "Price Per Unit Unavailable Online — Contact Us About This SKU" instead of a fake price.
+First, *reproduce it* — I confirmed against the live theme that the price section only renders the quote-only treatment when the storefront tag is present, and that these products didn't have it. Then, additively (nothing destructive, fully reversible), I added the missing storefront tag to the whole batch. Now the pages correctly show "Price Per Unit Unavailable Online — Contact Us About This SKU" instead of a fake price.
 
 ## The Lesson
 
diff --git a/src/data/projects.ts b/src/data/projects.ts
index bc4072e..39e9e97 100644
--- a/src/data/projects.ts
+++ b/src/data/projects.ts
@@ -12,78 +12,78 @@ export interface Project {
 
 export const projects: Project[] = [
   {
-    slug: 'fresh-cut-paper',
-    name: 'Fresh Cut Paper',
-    url: 'https://freshcutpaper.com',
-    tagline: 'Vibrant 3D paper flower cards and gifts for birthdays, anniversaries, Mother\'s Day, thank yous, sympathy, and more.',
-    description: 'Fresh Cut Paper creates stunning pop-up paper art — intricate 3D bouquets and greeting cards that unfold into sculptural masterpieces. Their e-commerce presence needed to match the magic of the product itself.',
-    challenge: 'Selling 3D handcrafted paper art online requires conveying depth and dimension that flat product photos can\'t capture. Seasonal demand spikes around Mother\'s Day and holidays were overwhelming inventory management, and the generic Shopify theme didn\'t reflect the brand\'s vibrant, artisanal identity.',
+    slug: 'handcrafted-gift-storefront',
+    name: 'Handcrafted Gift Storefront',
+    url: '',
+    tagline: 'A boutique e-commerce store for handcrafted paper art, greeting cards, and seasonal gifts.',
+    description: 'A boutique gift brand selling intricate handcrafted paper art and greeting cards. Their e-commerce presence needed to match the tactile, artisanal magic of the product itself.',
+    challenge: 'Selling handcrafted 3D paper art online requires conveying depth and dimension that flat product photos can\'t capture. Seasonal demand spikes around gifting holidays were overwhelming inventory management, and the generic theme didn\'t reflect the brand\'s vibrant, artisanal identity.',
     solutions: [
-      'Customized Shopify theme to enhance the visual appeal of pop-up designs with immersive product galleries',
+      'Customized the storefront theme to enhance the visual appeal of the designs with immersive product galleries',
       'Optimized site performance for faster browsing and mobile responsiveness across all devices',
       'Integrated apps for smooth inventory management and order processing to handle seasonal surges',
     ],
-    techStack: ['Shopify', 'Liquid', 'JavaScript', 'CSS3', 'App Integrations'],
+    techStack: ['Commerce Platform', 'Liquid', 'JavaScript', 'CSS3', 'App Integrations'],
     screenshot: '/images/projects/fresh-cut-paper.png',
   },
   {
-    slug: 'homekor',
-    name: 'HomeKor',
-    url: 'https://homekor.com',
-    tagline: 'Elevate your interior with curated art designs & mirrors. Custom frame your memories with our easy-to-use online photo framing tools.',
-    description: 'HomeKor brings gallery-quality art and custom framing to your home. The platform needed to handle complex product personalization while keeping the shopping experience effortless.',
-    challenge: 'Custom framing requires non-standard product configuration — customers need to select frame styles, mat colors, and dimensions, creating a multi-step checkout flow that most Shopify themes can\'t handle. Mobile users were abandoning carts due to poor responsive design on the configuration screens.',
+    slug: 'custom-framing-storefront',
+    name: 'Custom Framing Storefront',
+    url: '',
+    tagline: 'A home-decor storefront for curated art, mirrors, and custom online photo framing.',
+    description: 'A home-decor brand bringing gallery-quality art and custom framing online. The platform needed to handle complex product personalization while keeping the shopping experience effortless.',
+    challenge: 'Custom framing requires non-standard product configuration — customers need to select frame styles, mat colors, and dimensions, creating a multi-step checkout flow that most themes can\'t handle. Mobile users were abandoning carts due to poor responsive design on the configuration screens.',
     solutions: [
-      'Upgraded and optimized Shopify theme for a seamless shopping experience across all screen sizes',
+      'Upgraded and optimized the storefront theme for a seamless shopping experience across all screen sizes',
       'Integrated apps for custom framing and product personalization with intuitive step-by-step flows',
       'Improved site navigation and responsive design for both desktop and mobile users',
     ],
-    techStack: ['Shopify', 'Liquid', 'JavaScript', 'Custom Apps', 'Responsive Design'],
+    techStack: ['Commerce Platform', 'Liquid', 'JavaScript', 'Custom Apps', 'Responsive Design'],
     screenshot: '/images/projects/homekor.png',
   },
   {
-    slug: 'designer-wallcoverings',
-    name: 'DW Wallcoverings',
-    url: 'https://designerwallcoverings.com',
-    tagline: 'The leading architectural & interior designer resource for over 25 years. Natural, specialty, and custom wallcoverings.',
-    description: 'DW Wallcoverings is the premier destination for architects and interior designers sourcing luxury wallcoverings. With 25+ years in the trade, the platform needed to handle a massive, complex catalog.',
-    challenge: 'A catalog spanning thousands of SKUs across dozens of material types — natural fibers, vinyl, grasscloth, specialty finishes. Products needed complex categorization, high-resolution image galleries to show texture detail, and a checkout flow that supports the trade-to-retail pipeline.',
+    slug: 'specialty-catalog-storefront',
+    name: 'Specialty Catalog Storefront',
+    url: '',
+    tagline: 'A trade-facing storefront for a specialty product line with a large, complex catalog.',
+    description: 'A specialty commerce operation serving a trade audience. The platform needed to handle a large, complex catalog with deep categorization and high-fidelity imagery.',
+    challenge: 'A catalog spanning a large number of SKUs across many material types. Products needed complex categorization, high-resolution image galleries to show texture detail, and a checkout flow that supports the trade-to-retail pipeline.',
     solutions: [
-      'Customized Shopify theme to reflect premium branding and multi-line product presentation',
+      'Customized the storefront theme to reflect premium branding and multi-line product presentation',
       'Integrated apps for complex product catalogs and high-resolution image galleries',
       'Optimized checkout process and mobile responsiveness for trade and retail customers',
     ],
-    techStack: ['Shopify', 'Liquid', 'JavaScript', 'Algolia Search', 'Custom Metafields'],
+    techStack: ['Commerce Platform', 'Liquid', 'JavaScript', 'Search', 'Custom Metafields'],
     screenshot: '/images/projects/designer-wallcoverings.png',
   },
   {
-    slug: 'airsoft-eire',
-    name: 'Airsoft Eire',
-    url: 'https://airsofteire.com',
-    tagline: 'Customise your replica: optics, attachments & accessories, furniture, spray paint & camo tape.',
-    description: 'Airsoft Eire is Ireland\'s go-to shop for replica customization gear. The catalog is deep and technical — customers need to find exact parts that fit their specific builds.',
-    challenge: 'Accessories and attachments have complex compatibility requirements — customers need to find specific parts that fit their exact replica model. Slow site performance was losing mobile shoppers, and the lack of smart filtering made product discovery frustrating in a high-SKU catalog.',
+    slug: 'hobbyist-gear-storefront',
+    name: 'Hobbyist Gear Storefront',
+    url: '',
+    tagline: 'A deep, technical catalog storefront for a specialist hobbyist community.',
+    description: 'A specialist retailer serving a technical hobbyist community. The catalog is deep and technical — customers need to find exact parts that fit their specific builds.',
+    challenge: 'Accessories and attachments have complex compatibility requirements — customers need to find specific parts that fit their exact model. Slow site performance was losing mobile shoppers, and the lack of smart filtering made product discovery frustrating in a high-SKU catalog.',
     solutions: [
-      'Upgraded Shopify theme for measurably better performance and usability',
+      'Upgraded the storefront theme for measurably better performance and usability',
       'Integrated product filters, live search, and inventory management apps',
       'Enhanced navigation and mobile responsiveness for faster, friction-free shopping',
     ],
-    techStack: ['Shopify', 'Liquid', 'JavaScript', 'Search & Filter', 'Performance Optimization'],
+    techStack: ['Commerce Platform', 'Liquid', 'JavaScript', 'Search & Filter', 'Performance Optimization'],
     screenshot: '/images/projects/airsoft-eire.png',
   },
   {
-    slug: 'rose-and-harrys',
-    name: "Rose & Harry's NY",
-    url: 'https://roseandharrysny.com',
-    tagline: 'Specializing in tznius tops and t-shirts made of the highest quality fabrics, uniting fashion and function.',
-    description: "Rose & Harry's NY lives at the intersection of fashion and faith — creating contemporary, stylish clothing that meets modesty standards without compromising on design.",
-    challenge: 'A niche market where fashion meets faith. The brand needed to showcase contemporary, stylish clothing while clearly communicating modesty standards (tznius). The original theme didn\'t highlight fabric quality or fit details — the two things this audience cares most about.',
+    slug: 'apparel-storefront',
+    name: 'Apparel Storefront',
+    url: '',
+    tagline: 'A contemporary apparel storefront for a niche fashion community.',
+    description: "A niche apparel brand creating contemporary, stylish clothing for a specific community. The storefront needed to showcase design while clearly communicating the brand's standards.",
+    challenge: 'A niche apparel market with specific audience expectations. The brand needed to showcase contemporary, stylish clothing while clearly communicating its standards. The original theme didn\'t highlight fabric quality or fit details — the two things this audience cares most about.',
     solutions: [
-      'Customized Shopify theme to highlight quality craftsmanship and modern style',
+      'Customized the storefront theme to highlight quality craftsmanship and modern style',
       'Integrated apps for promotions, newsletter signup, and streamlined order management',
       'Optimized mobile experience and site speed for a smooth shopping journey',
     ],
-    techStack: ['Shopify', 'Liquid', 'JavaScript', 'Email Marketing', 'Mobile-First Design'],
+    techStack: ['Commerce Platform', 'Liquid', 'JavaScript', 'Email Marketing', 'Mobile-First Design'],
     screenshot: '/images/projects/rose-and-harrys.png',
   },
   {
@@ -134,7 +134,7 @@ export const projects: Project[] = [
   {
     slug: 'ai-wallpaper-storefront',
     name: 'AI Wallpaper Studio',
-    url: 'https://designerwallcoverings.com',
+    url: '',
     tagline: 'An original AI-generated wallpaper collection with a full seamless-tile quality pipeline.',
     description: 'A storefront for original, AI-generated wallpaper designs — each pattern generated in-house, quality-gated for seamless tiling, recolored across colorways, and rendered at print resolution. It pairs a generative design pipeline with a real commerce catalog, so novel patterns can go from prompt to purchasable product.',
     challenge: 'AI image models happily produce beautiful patterns that do not actually tile — a visible seam ruins a wallpaper. Designs also needed automated color and composition checks, full-resolution print masters, and at-scale mural previews that stay crisp, all before anything could ship to customers.',
@@ -143,7 +143,7 @@ export const projects: Project[] = [
       'Automated palette, composition, and defect checks plus a regenerate-until-clean loop so only production-quality designs ship',
       'Generated full-resolution print masters and crisp at-scale mural previews with per-colorway recoloring',
     ],
-    techStack: ['Node.js', 'Python', 'Generative AI', 'Computer Vision', 'PostgreSQL', 'Shopify'],
+    techStack: ['Node.js', 'Python', 'Generative AI', 'Computer Vision', 'PostgreSQL', 'Commerce Platform'],
     screenshot: '/images/projects/ai-wallpaper-storefront.png',
   },
   {
diff --git a/src/pages/hire.astro b/src/pages/hire.astro
index 9f3b8fa..541f38c 100644
--- a/src/pages/hire.astro
+++ b/src/pages/hire.astro
@@ -1341,7 +1341,7 @@
       <div class="nav-links">
         <a href="#skills" class="nav-link">SKILLS</a>
         <a href="#projects" class="nav-link">PROJECTS</a>
-        <a href="#furnishings" class="nav-link">FURNISHINGS</a>
+        <a href="#furnishings" class="nav-link">CATALOG</a>
         <a href="#platforms" class="nav-link">PLATFORMS</a>
         <a href="#services" class="nav-link">SERVICES</a>
         <a href="#inquiry" class="nav-cta">INQUIRE</a>
@@ -1383,7 +1383,7 @@
 
         <div class="hero-3d-container">
           <canvas id="hero-canvas" role="img" aria-label="Interactive 3D color wheel visualization"></canvas>
-          <div class="hero-3d-label">Interactive Color Wheel &mdash; Paint to Wallcovering</div>
+          <div class="hero-3d-label">Interactive Color Wheel &mdash; Color Matching</div>
         </div>
       </div>
     </div>
@@ -1432,7 +1432,7 @@
             <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"/></svg>
           </div>
           <h3 class="skill-title">E-Commerce</h3>
-          <p class="skill-techs">Shopify, Liquid, Storefront API, payment integration, product catalogs</p>
+          <p class="skill-techs">Commerce platforms, Liquid, storefront APIs, payment integration, product catalogs</p>
           <div class="skill-bar" aria-hidden="true"></div>
         </div>
 
@@ -1555,7 +1555,7 @@
           <img src="/images/tools/color-search.jpg" alt="Color Search tool screenshot" class="claude-card-image" loading="lazy" onclick="openLightbox(this)" />
           <div class="claude-card-body">
             <h3 class="claude-card-title">Color Search</h3>
-            <p class="claude-card-desc">AI color matching across 2,500+ products. Extract hex from any image, find coordinating patterns instantly.</p>
+            <p class="claude-card-desc">AI color matching across a large product catalog. Extract hex from any image, find coordinating patterns instantly.</p>
           </div>
         </div>
 
@@ -1563,15 +1563,15 @@
           <img src="/images/tools/coordinate-builder.jpg" alt="Coordinate Builder tool screenshot" class="claude-card-image" loading="lazy" onclick="openLightbox(this)" />
           <div class="claude-card-body">
             <h3 class="claude-card-title">Coordinate Builder</h3>
-            <p class="claude-card-desc">Drag-and-drop room boards for design presentations. Combine wallcoverings, fabrics, and trims visually.</p>
+            <p class="claude-card-desc">Drag-and-drop mood boards for design presentations. Combine products, materials, and accents visually.</p>
           </div>
         </div>
 
         <div class="claude-card">
-          <img src="/images/tools/paint-visualizer.jpg" alt="Paint Visualizer screenshot" class="claude-card-image" loading="lazy" onclick="openLightbox(this)" />
+          <img src="/images/tools/paint-visualizer.jpg" alt="Color Visualizer screenshot" class="claude-card-image" loading="lazy" onclick="openLightbox(this)" />
           <div class="claude-card-body">
-            <h3 class="claude-card-title">Paint Visualizer</h3>
-            <p class="claude-card-desc">Paint-to-wallcovering matcher. 14,000+ colors with brand filters. Behr, Benjamin Moore, Sherwin-Williams.</p>
+            <h3 class="claude-card-title">Color Visualizer</h3>
+            <p class="claude-card-desc">Color-to-product matcher. A large color library with filtering to find coordinating products instantly.</p>
           </div>
         </div>
 
@@ -1579,7 +1579,7 @@
           <div class="claude-card-placeholder">ROOM SETTING</div>
           <div class="claude-card-body">
             <h3 class="claude-card-title">Room Setting Generator</h3>
-            <p class="claude-card-desc">AI-generated photorealistic room visualizations. Bedroom, living room, office &mdash; see wallpaper in context before buying.</p>
+            <p class="claude-card-desc">AI-generated photorealistic room visualizations. Bedroom, living room, office &mdash; see products in context before buying.</p>
           </div>
         </div>
 
@@ -1595,7 +1595,7 @@
           <div class="claude-card-placeholder">EMAIL &rarr; SHOP &rarr; SOCIAL</div>
           <div class="claude-card-body">
             <h3 class="claude-card-title">Email &rarr; Shop &rarr; Social</h3>
-            <p class="claude-card-desc">Vendor email arrives &rarr; products auto-created in Shopify &rarr; social posts generated for Instagram, TikTok, LinkedIn.</p>
+            <p class="claude-card-desc">Vendor email arrives &rarr; products auto-created in the storefront &rarr; social posts generated for Instagram, TikTok, LinkedIn.</p>
           </div>
         </div>
 
@@ -1635,7 +1635,7 @@
           <img src="/images/tools/vendor-command-center.jpg" alt="Vendor Command Center screenshot" class="claude-card-image" loading="lazy" onclick="openLightbox(this)" />
           <div class="claude-card-body">
             <h3 class="claude-card-title">Vendor Command Center</h3>
-            <p class="claude-card-desc">Dashboard managing 50+ vendor agents. Health checks, cron schedules, SKU assignment, private label tracking.</p>
+            <p class="claude-card-desc">Dashboard managing dozens of vendor agents. Health checks, cron schedules, SKU assignment, catalog tracking.</p>
           </div>
         </div>
 
@@ -1790,11 +1790,11 @@
   <!-- SHOPIFY SOLUTIONS -->
   <section class="shopify-section" id="shopify">
     <div class="container">
-      <p class="section-label">FOR SHOPIFY STORE OWNERS</p>
+      <p class="section-label">FOR E-COMMERCE STORE OWNERS</p>
       <h2 class="section-title">Drowning in Product Data?</h2>
       <p class="shopify-lead">
         You have thousands of products, dozens of vendors, and not enough hours. These tools were built
-        to solve the exact problems that keep Shopify store owners up at night.
+        to solve the exact problems that keep e-commerce store owners up at night.
       </p>
 
       <div class="shopify-grid">
@@ -1811,7 +1811,7 @@
           <div class="shopify-card-number">02</div>
           <h3 class="shopify-card-title">Vendor Catalog Sync</h3>
           <p class="shopify-card-problem">Vendor prices change, products get discontinued, your store is always out of date.</p>
-          <p class="shopify-card-solution">Bi-directional sync engine. Imports vendor catalogs, detects price changes, flags discontinued items, and pushes updates to Shopify &mdash; respecting all API rate limits automatically.</p>
+          <p class="shopify-card-solution">Bi-directional sync engine. Imports vendor catalogs, detects price changes, flags discontinued items, and pushes updates to your storefront &mdash; respecting all API rate limits automatically.</p>
         </div>
 
         <!-- 3. Discontinued Product Manager -->
@@ -1827,7 +1827,7 @@
           <div class="shopify-card-number">04</div>
           <h3 class="shopify-card-title">Image Recovery Agent</h3>
           <p class="shopify-card-problem">200+ products with no images sitting live on your store, destroying conversion rates.</p>
-          <p class="shopify-card-solution">Hunts vendor websites for missing product images, validates formats, auto-uploads to Shopify. Products with no recoverable images get auto-drafted so they stop hurting you.</p>
+          <p class="shopify-card-solution">Hunts vendor websites for missing product images, validates formats, auto-uploads to your storefront. Products with no recoverable images get auto-drafted so they stop hurting you.</p>
         </div>
 
         <!-- 5. Smart Collection Builder -->
@@ -1843,7 +1843,7 @@
           <div class="shopify-card-number">06</div>
           <h3 class="shopify-card-title">Product Enrichment Pipeline</h3>
           <p class="shopify-card-problem">Your product data is shallow &mdash; generic descriptions, missing specs, can&rsquo;t compete with vendors who have rich pages.</p>
-          <p class="shopify-card-solution">Two-phase enrichment: crawls vendor sites for specs (dimensions, materials, fire ratings), then generates AI-powered descriptions. Backfills every field Shopify supports.</p>
+          <p class="shopify-card-solution">Two-phase enrichment: crawls vendor sites for specs (dimensions, materials, compliance ratings), then generates AI-powered descriptions. Backfills every field your commerce platform supports.</p>
         </div>
       </div>
 
@@ -1854,13 +1854,13 @@
     </div>
   </section>
 
-  <!-- HOME FURNISHINGS INDUSTRY -->
+  <!-- CATALOG COMMERCE INDUSTRY -->
   <section class="shopify-section" id="furnishings">
     <div class="container">
       <p class="section-label">INDUSTRY SOLUTIONS</p>
-      <h2 class="section-title">Home Furnishings &amp; Interior Design</h2>
+      <h2 class="section-title">Catalog-Heavy Commerce</h2>
       <p class="shopify-lead">
-        Purpose-built tools for brands, wholesalers, and retailers in the home furnishings space.
+        Purpose-built tools for brands, wholesalers, and retailers running large, catalog-heavy product lines.
         Each one runs autonomously in production &mdash; built by one operator with Claude Code, replacing what typically requires an entire dev team.
       </p>
 
@@ -1869,8 +1869,8 @@
         <div class="shopify-card">
           <div class="shopify-card-number">01</div>
           <h3 class="shopify-card-title">360&deg; Swatch Spin Engine</h3>
-          <p class="shopify-card-problem">Static product images don&rsquo;t sell fabric and material swatches &mdash; customers need to see texture.</p>
-          <p class="shopify-card-solution">Generates animated circular swatch GIFs at 2x internal resolution with Lanczos downscaling. Play-button overlay, smooth 180&deg; rotation, auto-uploads to Shopify. One command processes an entire vendor catalog.</p>
+          <p class="shopify-card-problem">Static product images don&rsquo;t sell textured goods &mdash; customers need to see the material up close.</p>
+          <p class="shopify-card-solution">Generates animated circular swatch GIFs at 2x internal resolution with Lanczos downscaling. Play-button overlay, smooth 180&deg; rotation, auto-uploads to the storefront. One command processes an entire vendor catalog.</p>
         </div>
 
         <!-- 2. Vendor Command Center -->
diff --git a/src/pages/projects/index.astro b/src/pages/projects/index.astro
index 81dfc79..74bd0f1 100644
--- a/src/pages/projects/index.astro
+++ b/src/pages/projects/index.astro
@@ -3,11 +3,11 @@ import BlogLayout from '../../layouts/BlogLayout.astro';
 import { projects } from '../../data/projects';
 ---
 
-<BlogLayout title="Projects" description="Shopify builds, e-commerce platforms, and production systems by Agent Abrams.">
+<BlogLayout title="Projects" description="E-commerce storefronts, data platforms, and production systems by Agent Abrams.">
   <section class="projects-hero">
     <p class="section-label">Case Studies</p>
     <h1>What I've Built</h1>
-    <p class="hero-subtitle">Real Shopify builds for real businesses. Each project came with unique challenges — here's how I solved them.</p>
+    <p class="hero-subtitle">Real e-commerce and full-stack builds for real businesses. Each project came with unique challenges — here's how I solved them.</p>
   </section>
 
   <section class="projects-grid">

← a277da0 security: scrub personal + sensitive info from public site,  ·  back to Goodquestion Ai  ·  security: full-genericize business secrets from public site, 715b360 →