<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Puinoib</title><description>Building and thinking in public. Notes on indie software, craft, and the slow work of making things people actually want. Written by Puinoib, a product maker.</description><link>https://puinoib.com</link><language>en</language><lastBuildDate>Fri, 07 Aug 2026 07:51:25 GMT</lastBuildDate><managingEditor>hi@piib.io (Puinoib)</managingEditor><webMaster>hi@piib.io (Puinoib)</webMaster><atom:link href="https://puinoib.com/rss.xml" rel="self" type="application/rss+xml"/><item><title>Don&apos;t Be a Better Trader</title><link>https://puinoib.com/blog/dont-be-a-better-trader</link><guid isPermaLink="true">https://puinoib.com/blog/dont-be-a-better-trader</guid><description>I spent months trying to improve my trading decisions. The real answer was not to trade at all.</description><pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I wrote a post two months ago called “&lt;a href=&quot;/blog/the-market-never-tells-you-why&quot;&gt;The Market Never Tells You Why&lt;/a&gt;.” The post was about trying to write down what had to be true before every trade, so I could compare my assumptions against what actually happened. I thought the answer was annotation. Write a baseline, compare after the fact, watch the patterns emerge.&lt;/p&gt;
&lt;p&gt;I tried it. It helped a little — mostly by slowing me down. But the bigger problem was upstream of annotation, and I did not see it yet.&lt;/p&gt;
&lt;h2 id=&quot;the-asymmetry-i-missed&quot;&gt;The asymmetry I missed&lt;/h2&gt;
&lt;p&gt;For a retail investor, the cost of being wrong is not symmetric with the cost of being right.&lt;/p&gt;
&lt;p&gt;If I buy a stock and it goes up, I keep most of the gain minus a small fee. If I buy a stock and it goes down, I keep the loss minus the same fee. Sounds neutral. It is not, because the people on the other side of my trade are not paying the same fees. They are paying lower fees, executing faster, working with better data, and they are not doing this in their spare time. They are doing it as their job, with infrastructure built for it. Every dollar I make above their costs, I take from them. Every dollar I lose, they take from me. I am playing a game in which my expected return, before I do anything, is already below zero.&lt;/p&gt;
&lt;p&gt;This is what the “trading is zero-sum” line in the older finance discourse is trying to get at, even if the framing is sloppy. It is not strictly zero-sum. It is negative-sum for anyone who is not a professional at it. The reasons are cost, information, and time. None of those go away with practice, because the other side is practicing too.&lt;/p&gt;
&lt;h2 id=&quot;what-my-drift-was-telling-me&quot;&gt;What my drift was telling me&lt;/h2&gt;
&lt;p&gt;I told myself I was a long-term investor. A value guy. I believed it. But somewhere along the way I started watching prices every day, checking positions, reading earnings calls for companies I had no edge on. The identity stayed the same. The behavior drifted. I did not notice the gap until I looked at my trade log and saw how often I had moved.&lt;/p&gt;
&lt;p&gt;I want to be careful about what that evidence shows. It shows I could not stay disciplined. It does not show that no one can. There are retail investors who hold for decades and do fine. There are professionals who trade constantly and beat the market. The drift in my log was evidence about me, not about the activity. I should not generalize from my failure to a verdict on the activity.&lt;/p&gt;
&lt;p&gt;But I also cannot pretend the failure was random. The reason I drifted is that the incentives around active trading are designed to produce drift. The price is always there. The news is always there. The app makes it one tap. Every hour spent looking is an hour the system is engineered to make you look. The drift is not a personal failing. It is the predictable outcome of being in an environment optimized for engagement, applied to a person with no special reason to be there.&lt;/p&gt;
&lt;h2 id=&quot;what-i-do-now&quot;&gt;What I do now&lt;/h2&gt;
&lt;p&gt;I do not trade. My portfolio has four holdings: a broad US equity index, a tech-heavy growth index, a dividend-growth fund, and US treasury bonds. That is it. No individual stocks, no sector bets, no timing. The allocation is meant to be held for a decade without touching it. I set it up, and I deleted the habit of checking.&lt;/p&gt;
&lt;p&gt;I will not pretend this is the only rational choice. There are people who can trade well and who do. I am not one of them, and I no longer want to find out whether I could become one. The expected value of trying, for me, is negative. The expected value of doing nothing is roughly the market return. I chose the second.&lt;/p&gt;
&lt;h2 id=&quot;what-i-kept-from-the-previous-post&quot;&gt;What I kept from the previous post&lt;/h2&gt;
&lt;p&gt;The previous post ended with “the market will never tell you why.” I still believe that. The annotation exercise taught me something, just not what I thought it would. It taught me to notice when I was about to act on a story I had not earned. That is a useful skill in places where the cost of being wrong is not denominated in dollars. I do not think the market is one of them.&lt;/p&gt;
&lt;p&gt;I do not check prices. I do not read earnings calls. I do not have a trade log. I have a portfolio I look at once a quarter, on a Sunday, when I am paying my bills.&lt;/p&gt;
&lt;p&gt;I stopped trying to be a better trader. I stopped trading. Those are not the same thing, but they end in the same place: I spend less time watching prices and more time doing work that compounds.&lt;/p&gt;</content:encoded><author>hi@piib.io (Puinoib)</author></item><item><title>What You Lose to the Build Step</title><link>https://puinoib.com/blog/what-you-lose-to-the-build-step</link><guid isPermaLink="true">https://puinoib.com/blog/what-you-lose-to-the-build-step</guid><description>I rebuilt a landing page with nothing but HTML and CSS and recovered something I could name: the immediacy between deciding and seeing. The real cost of the build step isn&apos;t bundle size. It&apos;s the gap it puts between you and your own page.
</description><pubDate>Wed, 01 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I rebuilt a landing page with an &lt;code&gt;index.html&lt;/code&gt; and a &lt;code&gt;&amp;#x3C;style&gt;&lt;/code&gt; tag. I went in expecting a nostalgia trip. I came out with the most satisfying afternoon of building I’d had in a long time.&lt;/p&gt;
&lt;p&gt;I spent the rest of the week trying to name why.&lt;/p&gt;
&lt;p&gt;What I’d stopped noticing was the distance between wanting something on the page and seeing it there. In plain HTML that gap is small. Edit a margin, save, refresh, and the button sits two pixels to the left. In a modern stack the same change travels through a component prop, a state update, a re-render, a reconciliation, a hydration check. Each step is reasonable in isolation. Strung together, they move the button off the center of your attention and put the toolchain there instead.&lt;/p&gt;
&lt;p&gt;That is the real cost. I had been paying it without noticing. By the time a change appeared on screen, I had often stopped thinking about the change and started thinking about the build.&lt;/p&gt;
&lt;p&gt;The debugging was where the difference showed up. When something broke, the search space was tiny. The markup was what I wrote. The CSS was what I wrote. I opened devtools and the element on screen was the element in my file. There was no stale closure hiding behind a virtual DOM, no effect firing because a dependency I’d missed changed shape. Half the time the fix was just reading my own code out loud.&lt;/p&gt;
&lt;p&gt;Performance wasn’t a goal and it arrived anyway. The page ships around 20 KB. Click a link and the next view is already there, because there is nothing to hydrate. I didn’t tune anything. I simply didn’t add the things that would have needed tuning.&lt;/p&gt;
&lt;p&gt;This works because the problem is small. A landing page is a solved shape. I was one person with one goal and no teammates to coordinate.&lt;/p&gt;
&lt;p&gt;What I gave up by going bare was real: no component reuse, no shared design system, no ergonomic way to add the next page. None of that mattered for a single page. The build step is the cost of coordination, and coordination is the cost of being more than one person with one page.&lt;/p&gt;
&lt;p&gt;The moment an app has real state, real routing, or a second contributor, the bare stack stops being a joy and starts being a liability. I’m not telling anyone to throw out their framework.&lt;/p&gt;
&lt;p&gt;But the experiment clarified something I’d been treating as the price of doing real work. The build step, the component library, the state manager — they exist to manage the distance between intent and rendered pixels. For the page in front of me that afternoon, the distance was the only thing they were adding.&lt;/p&gt;
&lt;p&gt;The browser had been ready the whole time.&lt;/p&gt;
&lt;p&gt;I had just stopped talking to it directly.&lt;/p&gt;</content:encoded><author>hi@piib.io (Puinoib)</author></item><item><title>AI Search Doesn&apos;t Want Better SEO</title><link>https://puinoib.com/blog/ai-search-doesnt-want-better-seo</link><guid isPermaLink="true">https://puinoib.com/blog/ai-search-doesnt-want-better-seo</guid><description>Generic product pages don&apos;t get penalized by AI search — they get compressed into the same sentence as every other generic product. Optimization won&apos;t fix that.
</description><pubDate>Thu, 18 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Google’s AI search has a favorite way to handle generic product pages: it neutralizes them into the same sentence as every other generic product in the category. Optimization won’t fix that. The problem is simpler than keyword coverage or heading structure. Your page sounds like everyone else’s.&lt;/p&gt;
&lt;p&gt;This is the search-specific version of a post I wrote on &lt;a href=&quot;/blog/agent-is-not-your-differentiator&quot;&gt;launch positioning&lt;/a&gt;. The mechanism is different. The fix is the same.&lt;/p&gt;
&lt;p&gt;I’ve been watching this happen on Shipstry and on other products I follow. Some pages get quoted in detail. Some get summarized in one sentence. Some don’t show up at all.&lt;/p&gt;
&lt;h2 id=&quot;three-patterns-that-get-compressed&quot;&gt;Three patterns that get compressed&lt;/h2&gt;
&lt;p&gt;The pages that get summarized away fall into three patterns.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The professional-sounding empty claim.&lt;/strong&gt; “Powerful AI platform that streamlines customer support workflows for modern teams.” It sounds right until you try to picture what it means. Compared to what? Which workflows? Which teams? The information density is zero.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The hollow proof section.&lt;/strong&gt; “Trusted by 500+ companies. 10x productivity improvement. Enterprise-grade security.” These might all be true. They also don’t help anyone make a decision. Which companies? Ten times improvement in what, measured how?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The SEO-driven FAQ.&lt;/strong&gt; Questions like “Is your product secure?” and “Do you offer a free trial?” appear on every SaaS page. They’re safe and expected. They also tell the reader nothing about what makes your product different. AI search has seen these exact questions a thousand times and doesn’t need to cite your version.&lt;/p&gt;
&lt;p&gt;All three share the same problem: AI can generate this content. And it has, thousands of times. When your page sounds like every other page, AI search has no reason to single yours out.&lt;/p&gt;
&lt;h2 id=&quot;what-gets-cited&quot;&gt;What gets cited&lt;/h2&gt;
&lt;p&gt;Google’s &lt;a href=&quot;https://developers.google.com/search/blog/2025/05/succeeding-in-ai-search&quot;&gt;guidance on succeeding in AI search&lt;/a&gt; is clear. Unique points of view, first-hand experience, specific evidence, non-commodity content. This is the same “helpful content” guidance from before, with a more visible penalty for generic writing.&lt;/p&gt;
&lt;p&gt;The difference is easier to see head to head. “Powerful AI platform that helps sales teams close more deals through intelligent automation and real-time insights” tells you nothing you could picture. “Turns scattered sales call notes into structured CRM updates without manual cleanup. Cuts post-call data entry from 25 minutes to 5 per call for B2B SaaS teams” tells you the user, the job, what changes, and by how much. If you were summarizing a category for a searcher, which would you quote?&lt;/p&gt;
&lt;p&gt;I’ve seen this play out on Shipstry in three ways.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Specific workflows beat feature lists.&lt;/strong&gt; When we listed features (voting, comments, Fog Mode, Trade Ports), the page was accurate but flat. When we rewrote it around the user’s workflow (“I submit my product, it goes into this week’s queue, people vote and comment”), the page started getting quoted. Readers could picture themselves using it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Honest positioning beats vague promises.&lt;/strong&gt; For Fog Mode, we could have written “Fair voting system for all products.” That sounds nice and says nothing. Instead we wrote what it actually does: “From 13:00 to 19:00 UTC daily, Shipstry hides vote counts and rankings so products get judged on merit rather than momentum.” Then we explained what we’re not doing: it doesn’t hide products, just the scoreboard during impression-forming hours. That distinction matters more than any tagline.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Real FAQs beat SEO templates.&lt;/strong&gt; The questions on our FAQ page came from launch comments, support tickets, and onboarding friction. “Does Fog Mode affect final rankings?” “Can I choose my own launch time?” These are questions that actually help someone decide. The template questions get answered but not featured, because they don’t differentiate.&lt;/p&gt;
&lt;p&gt;There’s a pattern across all three: each works because AI would struggle to generate it convincingly. The feature list is interchangeable. The honest positioning isn’t. The workflow explanation requires having watched people use the product. When content only you could write shows up, AI search has something worth quoting.&lt;/p&gt;
&lt;h2 id=&quot;the-unglamorous-truth&quot;&gt;The unglamorous truth&lt;/h2&gt;
&lt;p&gt;Structured data still matters. Product schema, FAQ schema, review schema. Get them right. But they’re just format. I’ve seen two pages with identical structured data where AI search quoted the one with better content. The schema was the same. The content was not.&lt;/p&gt;
&lt;p&gt;What AI search actually rewards hasn’t changed. Unique perspectives matter more than generic claims. A first-hand experience is worth paragraphs of polished copy. Helping someone make a decision is more valuable than listing every feature you have.&lt;/p&gt;
&lt;p&gt;That’s the whole game. Say something only your page can say, or accept that AI search will skip past you for the page that did.&lt;/p&gt;</content:encoded><author>hi@piib.io (Puinoib)</author></item><item><title>&apos;Agent&apos; Is Not Your Differentiator</title><link>https://puinoib.com/blog/agent-is-not-your-differentiator</link><guid isPermaLink="true">https://puinoib.com/blog/agent-is-not-your-differentiator</guid><description>Every AI launch calls itself an agent. The word names the category, not your product. Differentiation starts where the category label ends.
</description><pubDate>Tue, 09 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Every AI launch calls itself an agent. It’s become the default label, like “SaaS” was a decade ago. And it does exactly as much work for your launch as saying “SaaS” would: it names the category and nothing else.&lt;/p&gt;
&lt;p&gt;Nobody switches products because they thought “finally, an agent.” They switch because something specific gets done with less work, less delay, or less risk. The category label doesn’t help them picture that.&lt;/p&gt;
&lt;p&gt;I’ve been watching AI launches on Shipstry and Product Hunt for the past year. The ones that get real traction share something the generic ones don’t: they’re specific about what they actually do, who it’s for, and where the automation stops.&lt;/p&gt;
&lt;h2 id=&quot;own-a-workflow-not-a-label&quot;&gt;Own a workflow, not a label&lt;/h2&gt;
&lt;p&gt;“An AI agent for customer support” tells a buyer nothing they couldn’t guess. “Resolves refund and order-change tickets for Shopify brands without forcing a human to handle every exception” tells the buyer something useful.&lt;/p&gt;
&lt;p&gt;The difference isn’t marketing polish. One describes the category. The other describes the job.&lt;/p&gt;
&lt;p&gt;OpenAI’s &lt;a href=&quot;https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/&quot;&gt;practical guide to building agents&lt;/a&gt; makes a useful distinction here: an agent is a system that independently accomplishes tasks on the user’s behalf. Products that add an LLM without controlling workflow execution are not really agents in that sense. I think that distinction matters beyond semantics. If your launch uses “agent” because it sounds better than “tool,” the positioning is already vague.&lt;/p&gt;
&lt;p&gt;The template I keep coming back to is simpler than any framework: what annoying job does this product take off someone’s plate? If you can’t answer that in one sentence, the launch still sounds broader than the product feels in practice.&lt;/p&gt;
&lt;h2 id=&quot;show-where-autonomy-stops&quot;&gt;Show where autonomy stops&lt;/h2&gt;
&lt;p&gt;A generic AI launch promises magic. The trustworthy ones explain boundaries.&lt;/p&gt;
&lt;p&gt;Anthropic’s &lt;a href=&quot;https://www.anthropic.com/research/trustworthy-agents&quot;&gt;work on trustworthy agents&lt;/a&gt; frames the underlying tradeoff: agents need autonomy to be useful, but users need control over what the system can do and when it should check in. It is the same user-control problem as any software, just with higher stakes because the system is making more decisions on the user’s behalf.&lt;/p&gt;
&lt;p&gt;If your page doesn’t explain the handoff boundary, visitors will assume one of two bad things: the product is less capable than you claim, or it’s more reckless than they want.&lt;/p&gt;
&lt;p&gt;A simple line like “drafts responses automatically but requires approval before anything is sent” does more work than a paragraph about human-in-the-loop. So does “handles routine ticket triage on its own and escalates edge cases with the relevant context attached.” Buyers remember specifics.&lt;/p&gt;
&lt;p&gt;(I’ve seen the opposite too. A launch page that promised “full autonomy” and then buried in the fine print that the system still needed approval for certain actions. The page was trying to sound impressive and backpedaling at the same time. It read exactly as unconvincing as you’d expect.)&lt;/p&gt;
&lt;h2 id=&quot;proof-that-survives-a-second-look&quot;&gt;Proof that survives a second look&lt;/h2&gt;
&lt;p&gt;The category is full of polished demos. At this point, polish is not evidence.&lt;/p&gt;
&lt;p&gt;What people want to know is whether the product still works when the input is messy, the task is ambiguous, and the workflow isn’t a cherry-picked happy path. You don’t need to publish your full eval harness on the landing page. But you should surface the parts of proof that matter to a buyer: a real input instead of a cleaned-up example, a before-and-after workflow, a transcript excerpt, a screenshot of the review step, a “best for / not for” section, a short failure-case explanation.&lt;/p&gt;
&lt;p&gt;Google’s &lt;a href=&quot;https://developers.google.com/search/blog/2025/05/succeeding-in-ai-search&quot;&gt;AI search guidance&lt;/a&gt; says to focus on unique, non-commodity content. I think the same applies to launches. A commodity product page disappears in search for the same reason it disappears on launch day: it sounds like everyone else. The difference between a launch that gets shared and one that gets scrolled past is usually not the model or the feature list. It’s whether the page helps someone decide if this is for them.&lt;/p&gt;
&lt;h2 id=&quot;cut-before-you-add&quot;&gt;Cut before you add&lt;/h2&gt;
&lt;p&gt;Most launches need sharper edges, not more copy. Before adding another section, I’d cut these first:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“AI-powered” in the headline, if the product name already makes that obvious&lt;/li&gt;
&lt;li&gt;“for teams” or “for businesses,” which sounds ambitious until you notice everyone says it&lt;/li&gt;
&lt;li&gt;the architecture diagram in the hero&lt;/li&gt;
&lt;li&gt;“10x productivity” and other promises no buyer can sanity-check&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A page rarely becomes specific by addition. It becomes specific by editing.&lt;/p&gt;
&lt;p&gt;The word “agent” won’t do that work. The specific job, the honest boundary, and proof that survives scrutiny are what actually tell someone whether your product is for them.&lt;/p&gt;</content:encoded><author>hi@piib.io (Puinoib)</author></item><item><title>The Market Never Tells You Why</title><link>https://puinoib.com/blog/the-market-never-tells-you-why</link><guid isPermaLink="true">https://puinoib.com/blog/the-market-never-tells-you-why</guid><description>The market gives you the fastest feedback in the world. But it never tells you why. The only thing worth training is your ability to annotate it.
</description><pubDate>Thu, 28 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hand me an interface and my brain runs a loop I did not design: why is this designed this way, what breaks if you move it, who is this actually for. I’ve been a product manager for nearly five years, and the loop started before the title did. Now it runs without effort.&lt;/p&gt;
&lt;p&gt;I also tried to beat the market. I had accounts, held positions, watched prices move. I approached it the way I approach product work: find the variable, isolate it, learn from it.&lt;/p&gt;
&lt;p&gt;Same brain. Same ability to think in systems. One trained so deeply it became automatic. The other never started. The question that bothered me was why the same learning process did not transfer.&lt;/p&gt;
&lt;h2 id=&quot;its-not-about-feedback-speed&quot;&gt;It’s not about feedback speed&lt;/h2&gt;
&lt;p&gt;The obvious answer is feedback loops. Products give you data, A/B tests, iteration cycles. Investing gives you a number that refuses to explain itself.&lt;/p&gt;
&lt;p&gt;But that is not quite right either. The market gives you feedback faster than anything else. You buy and a second later the price tells you something. The problem is what it tells you — the price, and nothing else.&lt;/p&gt;
&lt;p&gt;The real asymmetry is the &lt;em&gt;shape&lt;/em&gt; of the feedback. When I ship a product change, I learn about it from several channels at once: the metric, a session replay, a support ticket, a coworker who tried it and hated it. Each one is a partial signal. The actual learning happens in the disagreement between them — when the metric is fine but the support tickets are bad, when the A/B test is positive but my designer thinks the new flow is worse. I do not have a labeled variable. I have several unlabeled ones, and the space between them is where the signal lives.&lt;/p&gt;
&lt;p&gt;The market gives me one channel. The price. A price movement is not triangulable. There is no replay. There is no coworker who tried my trade and hated it. The feedback is a single number, with no metadata, attributed to no cause.&lt;/p&gt;
&lt;p&gt;That is the asymmetry. Not speed. Not even “unlabeled.” It is that product feedback is a conversation between multiple signals, and market feedback is a monologue.&lt;/p&gt;
&lt;h2 id=&quot;what-i-tried-anyway&quot;&gt;What I tried anyway&lt;/h2&gt;
&lt;p&gt;I tried to manufacture triangulation. Before every trade, I wrote down one thing: what has to be true for this to work. Not a prediction. A baseline.&lt;/p&gt;
&lt;p&gt;It helped a little. I started noticing which of my assumptions held up and which were noise dressed up as conviction. The “catching my own drift” thing is real.&lt;/p&gt;
&lt;p&gt;But the help was thin, and I want to be honest about why. The baseline I wrote down was still a story I told myself, just one I told before the fact. The comparison after the fact was a comparison between two of my own stories, with no external reference. The triangulation was me triangulating against myself. Which is not triangulation.&lt;/p&gt;
&lt;p&gt;What it actually did was slow me down. Which is its own kind of value. The annotation did not teach me the market. It taught me to notice when I was about to act on a story I had not earned.&lt;/p&gt;
&lt;h2 id=&quot;what-the-loop-is-for&quot;&gt;What the loop is for&lt;/h2&gt;
&lt;p&gt;The loop I run on interfaces — why is this designed this way, what breaks if you move it, who is it actually for — works because the object of analysis is something I can take apart and ask questions of. A market is something that just happens, in aggregate, to everyone at once, for reasons no participant can fully trace.&lt;/p&gt;
&lt;p&gt;I can still train the discipline of slowing down before I act. I can still train the habit of writing down my reasons. I can still train the willingness to be told I was wrong without rewriting why.&lt;/p&gt;
&lt;p&gt;But the market is not the place where most of that learning happens. It is, at best, a place where I get to practice it under conditions that punish mistakes in dollars instead of in meetings. The market will never tell me why. That part is still true. The market also is not the place where I can learn most of what I actually need to learn.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Update, July 2026: I changed my mind. You don’t need to be a better trader — you don’t need to trade at all. &lt;a href=&quot;/blog/dont-be-a-better-trader&quot;&gt;Don’t Be a Better Trader&lt;/a&gt; explains why.&lt;/em&gt;&lt;/p&gt;</content:encoded><author>hi@piib.io (Puinoib)</author></item><item><title>Four Questions a Product Page Can&apos;t Fake</title><link>https://puinoib.com/blog/four-questions-a-product-page-cant-fake</link><guid isPermaLink="true">https://puinoib.com/blog/four-questions-a-product-page-cant-fake</guid><description>Most product SEO pages are optimized for search but don&apos;t help anyone decide. I&apos;ve settled on a simpler test: four questions the page must answer before anyone leaves.
</description><pubDate>Tue, 12 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Most product SEO pages are optimized for search but not for decisions. They check every box in the template. And they still don’t help anyone decide whether to try the product.&lt;/p&gt;
&lt;p&gt;I used to think the fix was better keywords or better structure. I’ve spent enough time watching real visitors land on product pages to change my mind. The pages that convert answer four questions. The rest just look like they should.&lt;/p&gt;
&lt;p&gt;This assumes one thing first, though: the page type already matches what the visitor is searching for. A “best tool” query wants a comparison page, a “how do I do X” query wants a guide, a “tool for my situation” query wants a use-case page. Point the wrong page type at a query and no amount of structure rescues it. Once that match is right, four questions decide whether the page actually helps.&lt;/p&gt;
&lt;h2 id=&quot;1-is-this-for-my-kind-of-problem&quot;&gt;1. Is this for my kind of problem?&lt;/h2&gt;
&lt;p&gt;This sounds obvious. It gets missed constantly.&lt;/p&gt;
&lt;p&gt;Hero sections love to sound important: “Modern customer feedback platform.” “Next-gen product analytics.” The problem with these is they don’t eliminate doubt. Someone landing on the page still has to guess whether this is the right place.&lt;/p&gt;
&lt;p&gt;The ones that work remove doubt fast. “Customer feedback portal for SaaS teams.” “Bug reporting tool for mobile apps.” The specificity does more work than the polish ever could.&lt;/p&gt;
&lt;p&gt;Some products genuinely serve multiple audiences. The fix is not to pick one and hide the rest, but to make the primary one unmistakable and let the other audiences get their own landing page. A page that tries to speak to everyone usually ends up speaking to no one.&lt;/p&gt;
&lt;p&gt;I’ve made this mistake too. Early Shipstry pages led with what I thought was a strong value prop. The bounce rate told me visitors couldn’t tell if they belonged there. Narrowing the opening to one clear use case helped more than any hero redesign.&lt;/p&gt;
&lt;h2 id=&quot;2-what-changes-if-i-use-it&quot;&gt;2. What changes if I use it?&lt;/h2&gt;
&lt;p&gt;People don’t search because they want to admire software. They search because the current workflow is annoying.&lt;/p&gt;
&lt;p&gt;The best product pages describe the before state: feedback scattered across email, Slack, and screenshots. Launch traffic arriving with no simple way to compare products. Support answering the same questions because knowledge is trapped in people’s heads.&lt;/p&gt;
&lt;p&gt;Then they show what actually changes: scattered feedback becomes a single stream. Launch comparisons happen in one place. Knowledge stays accessible instead of living in someone’s inbox.&lt;/p&gt;
&lt;p&gt;What matters here is that the reader can picture their own workflow improving. “Custom dashboards” doesn’t do that. “Turns messy event streams into reports a PM can use without rebuilding everything” does. The page earns its keep when the before-and-after is specific enough to recognize.&lt;/p&gt;
&lt;h2 id=&quot;3-why-should-i-believe-the-claim&quot;&gt;3. Why should I believe the claim?&lt;/h2&gt;
&lt;p&gt;Good structure helps, but it doesn’t create trust on its own.&lt;/p&gt;
&lt;p&gt;At some point the visitor needs a reason to believe. That proof can take different forms: screenshots with context, sample outputs, a short before-and-after workflow, a clear “best for / not for” section, FAQ answers drawn from real objections.&lt;/p&gt;
&lt;p&gt;That last one matters more than it gets credit for. I like FAQ sections when they come from actual sales calls and support tickets, not when they exist just because every template says to add one. A good FAQ doesn’t pad the page. It removes repeat uncertainty. (I once wrote an FAQ section that looked complete and professional. It answered questions nobody was asking. The real questions, the ones that kept coming up in support, were different and more specific. I replaced the whole section and the page improved.)&lt;/p&gt;
&lt;h2 id=&quot;4-what-is-the-next-step&quot;&gt;4. What is the next step?&lt;/h2&gt;
&lt;p&gt;By the bottom of the page, the reader isn’t asking “what is this?” anymore. They’re asking what to do next if the page looks promising.&lt;/p&gt;
&lt;p&gt;That next step should match the intent that brought them there. For high-intent searches, “Start free” or “Book a demo” works fine. For mid-intent searches, softer steps convert better: see sample outputs, explore templates, read implementation details.&lt;/p&gt;
&lt;p&gt;Asking too much too early is still friction, even if the button looks nice. I’ve learned this on Shipstry: the pages that let visitors explore before committing perform better than the ones that push for signup immediately.&lt;/p&gt;
&lt;h2 id=&quot;a-simpler-test&quot;&gt;A simpler test&lt;/h2&gt;
&lt;p&gt;If I need to judge a product page quickly, I check whether a visitor can answer these four questions without much work:&lt;/p&gt;
&lt;p&gt;Is this for my kind of problem?
What changes if I use it?
Why should I believe the claim?
What is the next step?&lt;/p&gt;
&lt;p&gt;If the page answers those clearly, it’s usually in good shape. If it doesn’t, another SEO checklist rarely fixes the deeper problem — it just makes the brochure longer.&lt;/p&gt;</content:encoded><author>hi@piib.io (Puinoib)</author></item><item><title>Why I Hide the Scoreboard</title><link>https://puinoib.com/blog/why-i-hide-the-scoreboard</link><guid isPermaLink="true">https://puinoib.com/blog/why-i-hide-the-scoreboard</guid><description>A launch platform is a piece of interface design. When it puts visible momentum first, it teaches users to outsource judgment to the scoreboard. Fog Mode is one way to push back.
</description><pubDate>Tue, 28 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Launch platforms talk a lot about exposure.&lt;/p&gt;
&lt;p&gt;What they rarely talk about is what they train people to notice.&lt;/p&gt;
&lt;p&gt;A launch platform is not just a list of products. It is a piece of interface design. It decides what shows up first, what feels important, and how the user judges what they see.&lt;/p&gt;
&lt;p&gt;Most of the time, that judgment is not really about the product. It is about momentum.&lt;/p&gt;
&lt;p&gt;The product that already looks ahead gets treated as safer and more worth checking first. The product that starts slower has to fight two battles at once: getting noticed, and looking like it is already behind.&lt;/p&gt;
&lt;h2 id=&quot;visible-momentum-compounds&quot;&gt;Visible momentum compounds&lt;/h2&gt;
&lt;p&gt;Most launch systems quietly teach the same behavior: check the board, then check the product. Nobody has to say it. The interface says it for them.&lt;/p&gt;
&lt;p&gt;You open a leaderboard, see which products are climbing, and your brain fills in the rest. Maybe that one is winning for a reason. Maybe the ones lower down can wait.&lt;/p&gt;
&lt;p&gt;Early momentum is noisy. It can come from a large existing audience, timezone luck, coordinated support, or just being seen first. Once that momentum becomes visible, it starts compounding. Discovery drifts from product judgment toward inherited advantage.&lt;/p&gt;
&lt;p&gt;Every launch platform rewards something, whether it admits it or not. Some reward quality, some taste, the rest just amplify whoever already has an audience. The problem starts when the product itself becomes secondary to the numbers climbing around it. At that point, the platform is no longer just helping people discover products. It is teaching them to outsource judgment.&lt;/p&gt;
&lt;h2 id=&quot;fog-mode&quot;&gt;Fog Mode&lt;/h2&gt;
&lt;p&gt;Fog Mode is Shipstry’s daily blind-voting window. Mechanically that means once a day, for a fixed window, Shipstry hides the three things most likely to distort a first impression: public rank, visible vote counts, and the feeling that one product is already supposed to win.&lt;/p&gt;
&lt;p&gt;Votes still count. Fog Mode does not freeze the launch or add a secret scoring system. It removes the public scoreboard while people are still forming a first impression.&lt;/p&gt;
&lt;p&gt;It does not hide the products themselves either. You can still read the launch, inspect the maker, open the product page, read comments, compare screenshots, and decide whether the product deserves your attention. The substance stays. The crowd cues drop away.&lt;/p&gt;
&lt;p&gt;That is not free. Without a scoreboard, voters do more work to compare products during the window. The trade is that they form their judgment from the product, not the rank. For makers with an existing audience, that is friction. For makers without one, it is the only level field the platform offers.&lt;/p&gt;
&lt;p&gt;That is the design principle underneath all of it: hide the most distortive signal, keep the product legible.&lt;/p&gt;
&lt;p&gt;I considered more complicated versions: personalized fog windows, adaptive hiding rules, different thresholds for different products. I did not want that. Fog Mode works because the rule is simple and public. It starts at a fixed time, ends at a fixed time, and everyone knows what changes during that window. Predictability matters. If a fairness mechanism feels arbitrary, people stop trusting it.&lt;/p&gt;
&lt;h2 id=&quot;interfaces-are-not-neutral&quot;&gt;Interfaces are not neutral&lt;/h2&gt;
&lt;p&gt;If a platform can shape what people notice, it can also shape what they overvalue. Rank, vote count, and visible momentum are not harmless decoration. They change behavior. They steer attention before a user has made up their own mind.&lt;/p&gt;
&lt;p&gt;That means discovery platforms do not just reflect competition. They design it.&lt;/p&gt;
&lt;p&gt;Fog Mode is a constraint on my own design. The choice behind it is:&lt;/p&gt;
&lt;p&gt;Do you want a launch platform to amplify reflexes, or judgment?&lt;/p&gt;
&lt;p&gt;Do you want users to read the room first, or the product first?&lt;/p&gt;
&lt;p&gt;My answer was clear enough that I turned it into a feature.&lt;/p&gt;</content:encoded><author>hi@piib.io (Puinoib)</author></item><item><title>The Maintenance Window Is the Real Work</title><link>https://puinoib.com/blog/maintenance-window-is-the-real-work</link><guid isPermaLink="true">https://puinoib.com/blog/maintenance-window-is-the-real-work</guid><description>A live production upgrade with hard gates taught me more about building durable software than any feature launch. The migration was the easy part.
</description><pubDate>Tue, 14 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A maintenance window with hard gates tells you whether you actually trust your system. Not in theory, in practice. I ran one on Shipstry that took 24 minutes and taught me more about building durable software than three months of feature work.&lt;/p&gt;
&lt;p&gt;Feature work is the easy thing to talk about. Screenshots, launches, changelog entries. There’s always something visible to point at. I’d been doing that for months: comments, badges, discovery pages, flexible pricing.&lt;/p&gt;
&lt;p&gt;The less visible work is what happens when the data model under those features stops being a clean fit. Feature work lets you ship something and call it done; maintenance work is when you have to defend what you already shipped. That was the work that taught me what I actually trust.&lt;/p&gt;
&lt;h2 id=&quot;why-i-stopped-trusting-my-own-migration-history&quot;&gt;Why I stopped trusting my own migration history&lt;/h2&gt;
&lt;p&gt;The upgrade had two jobs: split a unified comment table into product and blog comments, and replace a single &lt;code&gt;order&lt;/code&gt; model with a cleaner payment domain, &lt;code&gt;payment_order&lt;/code&gt;, &lt;code&gt;purchase&lt;/code&gt;, &lt;code&gt;product_submission_purchase&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Neither was technically hard. Both required answering a question I couldn’t shortcut: does the data in production match what my assumptions say it should?&lt;/p&gt;
&lt;p&gt;The answer came back no, before I’d even started the main cutover. I checked for old pricing-tier values that earlier migrations should have cleaned up. They were still sitting in production. It meant I couldn’t trust migration history in the abstract — only the database I was actually about to operate on — so I reran the normalization first. Production has no interest in your assumptions, and this work gets easier once you stop arguing with it.&lt;/p&gt;
&lt;p&gt;Before touching anything, I exported production D1 and recorded baselines for every table I was about to modify. Legacy comment count. Legacy order count. How many backlinks purchases referenced the old model. The exact paid total for every product that had gone through an earlier pricing tier.&lt;/p&gt;
&lt;p&gt;That last one turned out to be the key. When I backfilled historical data into the new payment model, some old &lt;code&gt;order&lt;/code&gt; rows couldn’t tell me the precise boundary between an original submission and a later upgrade. The schema hadn’t stored that distinction.&lt;/p&gt;
&lt;p&gt;I had a choice: invent the missing data to make the new schema look complete, or keep the backfill conservative and live with the gap.&lt;/p&gt;
&lt;p&gt;I chose the second option. Cleanly modeled fiction is still fiction. The database is not the place to make things look neat at the expense of accuracy.&lt;/p&gt;
&lt;h2 id=&quot;the-maintenance-switch-is-the-real-work&quot;&gt;The maintenance switch is the real work&lt;/h2&gt;
&lt;p&gt;The single most important thing I did before the upgrade was not a migration script. It was a centralized &lt;code&gt;MAINTENANCE_WRITE_FREEZE&lt;/code&gt; guard wired through every endpoint that mutates D1: checkout creation, Stripe webhooks, comments, likes, votes, profile updates, admin actions, draft flows, notification endpoints.&lt;/p&gt;
&lt;p&gt;If the migration scripts failed, I still had control. That’s the difference between a maintenance window and an incident.&lt;/p&gt;
&lt;h2 id=&quot;the-one-surprise&quot;&gt;The one surprise&lt;/h2&gt;
&lt;p&gt;The first run of the payment backfill failed. Not because the logic was wrong or the data was bad. D1 remote execution refused the explicit SQL transaction wrapper in the file.&lt;/p&gt;
&lt;p&gt;If I’d been running the window without a write freeze, that failure would have been a problem. With the freeze in place, it was just friction: remove the explicit &lt;code&gt;BEGIN TRANSACTION&lt;/code&gt; / &lt;code&gt;COMMIT&lt;/code&gt;, rerun, verify the gate counts still matched, move on.&lt;/p&gt;
&lt;p&gt;The failure didn’t matter because the system around it was designed to absorb failures. That was the whole point of the window: not to execute the scripts perfectly, but to have a setup where surprises stay small.&lt;/p&gt;
&lt;p&gt;(I should probably have tested the transaction syntax against D1 remote before the window. I didn’t. Next time.)&lt;/p&gt;
&lt;h2 id=&quot;what-changed&quot;&gt;What changed&lt;/h2&gt;
&lt;p&gt;The schema looks different now. The payment model is cleaner. Comments know whether they belong to a product or a blog post. Historical backlinks access still works. Old paid amounts still count toward upgrades.&lt;/p&gt;
&lt;p&gt;But the real change is less visible. The exercise of planning the window, building the guard, recording baselines, and validating each gate forced me to understand my own system at a level that feature work never does. You don’t really know a codebase until you’ve had to prove, under a write freeze, that every assumption you made about the data is still true.&lt;/p&gt;
&lt;p&gt;I wouldn’t trade those 24 minutes for another three months of features. Both matter, but only the maintenance window told me whether I actually trust what I built. Shipstry now has a foundation I trust to keep building on.&lt;/p&gt;</content:encoded><author>hi@piib.io (Puinoib)</author></item><item><title>The Performance Trap of &apos;Build in Public&apos;</title><link>https://puinoib.com/blog/performance-trap-of-build-in-public</link><guid isPermaLink="true">https://puinoib.com/blog/performance-trap-of-build-in-public</guid><description>Build in Public has become performance art. Its real cost lands on the solo developer during the Silent Phase, the stretch where the dashboard goes flat and patience turns into a trap.
</description><pubDate>Fri, 27 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Build in Public has turned into performance art. We celebrate the $10k MRR screenshots and the “Product of the Day” badges. Nobody posts about the part that actually sinks solo developers: the Silent Phase, the long stretch where the dashboard stays flat and the only feedback comes from your own linter.&lt;/p&gt;
&lt;p&gt;The standard advice is patience. Patience alone is a trap, because it usually masks a lack of direction.&lt;/p&gt;
&lt;h2 id=&quot;code-is-a-liability-in-a-solo-setup&quot;&gt;Code is a liability in a solo setup&lt;/h2&gt;
&lt;p&gt;When the dashboard is flat, the instinct is to build your way out. Ship new features to soothe the anxiety that nobody is using the thing. In a solo setup, every line of code you write is a liability from the day you write it. It adds technical debt and support load before it earns a single user.&lt;/p&gt;
&lt;p&gt;A solo founder’s leverage shows up most in the features they had the courage to delete.&lt;/p&gt;
&lt;h2 id=&quot;the-harder-work-is-shipping-clarity&quot;&gt;The harder work is shipping clarity&lt;/h2&gt;
&lt;p&gt;Spending two days refactoring CSS or tweaking a database schema feels like progress. Usually it is “productive procrastination,” an escape from figuring out why the first ten users did not stay.&lt;/p&gt;
&lt;p&gt;Shipping code is the easy part of being an indie hacker. Shipping clarity is the hard part.&lt;/p&gt;
&lt;h2 id=&quot;build-for-the-morning-after-the-launch&quot;&gt;Build for the morning after the launch&lt;/h2&gt;
&lt;p&gt;The morning after the launch is the real test. By then the hype has burned off and only the utility of your code is left. If the product is not already useful by then, no amount of “build in public” performance will save it.&lt;/p&gt;
&lt;p&gt;The quiet days are not a waiting room. They are the test.&lt;/p&gt;</content:encoded><author>hi@piib.io (Puinoib)</author></item></channel></rss>