3
15 Comments

Finance guy, zero coding experience. I shipped a phone-verified social platform in three months with a two-Claude workflow. Here's the proce

https://veris.social/?ref=indiehackers

Five months ago I had zero software experience. I work in finance, budgets and forecasting for a college athletics department. In July I merged the last slice of Veris (https://veris.social/?ref=indiehackers), a social platform where every account is a phone-verified human, the feed is chronological and follow-only, and nothing is optimized to make you angry. Private beta, waitlist open.

What shipped: phone OTP auth, OAuth account linking as identity signals, a trust-tier system, feeds, follows, likes, replies, soft-delete with a grace window, full account deletion, scheduled DB jobs, dark mode, a design system. Next.js and Supabase, all of it built through Claude.

The setup: two Claudes, strict separate roles

Claude.ai (web) is the planner and reviewer. Architecture, tradeoffs, explaining every new concept in plain English before we use it, reviewing every output before anything runs.

Claude Code (terminal) is the executor. "Ask before running" stayed ON for the entire build. I approved every command for three months. Slower, and the reason I actually understand my own stack now.

Rules that saved me, repeatedly

  1. Vertical slices. 13 of them, each a complete end-to-end feature, merged one at a time. Never two half-built things at once. When something broke, I always knew which slice did it.

  2. A decisions log that records rejected alternatives, not just choices. When a bug showed up weeks later, the entry explaining why we did NOT do the obvious thing was usually the fix.

  3. Never trust "Success. No rows returned." After every database write, run a query that proves the write happened. This one habit caught a bug that had been silently failing for six weeks. The UI looked right the whole time.

  4. Plan before doing. Nothing gets executed until the planner has laid out what's about to happen and why, and I've said yes. Most bad ideas died here, before they cost anything.

  5. Ask for pushback. My standing instruction is to challenge my ideas. It has talked me out of at least four decisions I was sure about. Every one of them would have hurt.

  6. Files are the memory. Separate chats don't share history, so a spec, a decisions log, and a README tracker live in project knowledge and get re-uploaded after every change. New chat, read the files, continue.

  7. Allow-list a command only after it's been seen working safely several times. Everything else keeps its prompt. Learning phase means prompts on.

What broke, because plenty did

  • A scheduled job that was only half registered. Every check said it was fine. Only the proof query showed one of two jobs missing.
  • A trust score that the UI displayed correctly while the database never got the update. Six weeks. See rule 3.
  • An OAuth provider that had never been fully configured on the provider's side. Worked in every test we ran, because every test used the other provider. Surfaced on launch day when I tried to link my own account.
  • Me, skipping the plan step whenever I got excited. That's usually when the mess started.

The business side, since this is IH: bootstrapped, solo, side project alongside a day job, pre-revenue. Ads are off the table by design. The model isn't decided yet, and I'd rather say that than make one up. Right now the goal is a waitlist worth showing and a beta that proves people want a network where every account is a verified human.

Happy to go deep on the workflow or the product in the comments, including what broke.

submitted this linkon September 19, 2026
  1. 1

    Really solid approach — I'm juggling something similar myself (building Xstream4K on the side), what's been the hardest part for you so far?

    1. 1

      Hardest part so far: distribution, not building. The build had a workflow and a rhythm. Getting strangers to see it means starting from zero on every platform, each with its own gate for new accounts, and there's no slice for that. Second hardest: keeping "ask before running" on when I was tired and wanted to go faster. That one I'm glad I held.

  2. 1

    Thanks for sharing the numbers, that makes it much easier to follow.

  3. 1

    Interesting. How are you measuring whether it is working?

    1. 1

      Two numbers. Waitlist signups by source (every link carries a ref tag, so I can see which channel each signup came from) and site visits in Vercel Analytics. Right now the honest metric is "does anyone who isn't a friend sign up," and the answer is a small yes. The real test comes when the gate opens and people can try it.

  4. 1

    Clear and practical, thanks. Did anything surprise you along the way?

    1. 1

      How much of the work wasn't code. The build took three months. The launch has been about accounts, dashboards, registration steps I'd never heard of, and community rules. The other surprise: the proof-query habit caught more bugs than any tool I used. "It says success" turned out to mean almost nothing.

  5. 1

    Good write-up. What would you do differently if you started again?

    1. 1

      Start the community accounts on day one, not launch week. Every place I want to post gates new accounts, and I showed up new. Also: write down the assumption behind every constraint, not just the constraint. A commenter here pointed that out and it's already changed how I keep the decisions log.

  6. 1

    The "proof query after write" and decision-log habits are absolute gems—most senior engineers take years to learn those the hard way. Splitting Claude into a Planner/Architect vs Executor role is probably the sharpest operational setup for AI-assisted building right now. One hidden risk area to keep on your radar as you scale phone/OAuth identity verification alongside a day job: identity and environment leakage. If you're building on personal hardware while on the same home network as a work device, corporate EDRs (like CrowdStrike or Zscaler) actively capture subnet-level DNS queries to Supabase/Next.js backends. Likewise, global git configurations frequently leak work email headers or enterprise keys directly into public commits if you don't explicitly scope directory paths.For the business side, keep an eye on timestamp overlap between your commit logs and day-job hours—corporate legal teams use timestamp convergence far more often than code inspection during IP due diligence. Awesome build, and keeping "Ask before running" enabled was definitely the right call!

    1. 1

      Thanks, this is useful. Taking the three in turn.

      Git config: fair, and I'm checking today. The repo is private right now, but history is permanent if it ever opens, so the author email on every commit is worth verifying now rather than later.

      Timestamps: this is the one that lands hardest. Everything was built on personal hardware, personal accounts, personal time. But "personal time" is a claim, and the commit log is the evidence. I'm going to review the timestamp pattern and my employer's IP policy before any investor conversation, not after. Appreciate the nudge.

      Network: I think this one is overstated. Endpoint tools like CrowdStrike or Zscaler run on the work device and see that device's traffic. Sharing a home router doesn't put my personal laptop's DNS in their view. If someone knows a real case of subnet-level capture from a consumer network, I'd genuinely want to read it, but I don't think it's the risk profile here.

      And yes, "ask before running" stays on. It's the one setting I'd tell any non-coder not to touch.

      1. 1

        Glad the timestamp and git points resonated—checking those early before investor DD is easily the highest-ROI move you can make.
        On the network side, you're 100% right on standard host setups. A CrowdStrike sensor on a work machine isn't sniffing raw Wi-Fi packets off your personal laptop. Where I’ve seen people get burned isn't raw packet capture, but DNS resolver convergence on the local router. When a work Mac is running a cloud security agent (like Zscaler) with local bypass policies, local domain lookups and mDNS queries often bleed through shared gateway resolvers or local split-tunnel rules. It’s less "corporate spyware watching your home network" and more "sloppy local DNS routing logging Supabase/Vercel endpoints into tenant audit logs."
        That said, if you're on personal hardware with clean local configs, you're already ahead of 95% of builders out there. Rooting for Veris Social—keeping that decisions log tight is going to save you massive headaches down the road!

        1. 1

          Appreciate the detail, and the walk-through of where it actually bites. Not my setup, but it's a good reminder that "personal hardware" is a claim you have to be able to back up device by device, not just say.

          Git and timestamp checks are on this week's list. Thanks for rooting for it.

  7. 1

    Your decisions log rule is the part I’d want to steal from this workflow.

    One thing I’d be curious about after three months: do you record only why an alternative was rejected, or also what would have to change for you to reconsider it?

    I’ve been thinking there’s an important difference between:

    a fixed constraint,
    a decision that’s the current default,
    and an option rejected because of assumptions that may later stop being true.

    Otherwise a new Claude can read the history perfectly and still inherit an old decision as if it were permanent.

    Did that ever happen in practice — where the decisions log preserved context, but made an earlier choice feel more settled than it really was?

    1. 1

      Honest answer: the log doesn't formally separate those three, and your framing is better than my practice. What evolved organically is a "Rejected:" line on most entries and a "revisit when" line on some, but not consistently.

      Where it worked: the biggest infrastructure decision (staying on the free database tier and a trial SMS account) was recorded as a deferral with explicit triggers, not a choice. "Revisit at invite scale or funding." And the one known security gap that's still open is logged as "must close before signups open past the trusted circle," so no future chat can read it as settled.

      Where it bit me: the phone number is the only login credential in v1. That was recorded as architecture, so every later chat treated it as fixed. Nobody wrote down "this assumes every account owner controls their number forever." Then I went to create the official brand account on a work phone I don't durably own, and the planner had to talk me out of it on the spot. The constraint was real. The assumption behind it had never been named, so nothing flagged it until the exact case it didn't cover showed up.

      What catches this today is soft: every chat starts by re-reading the files, and my standing instruction is to push back. That surfaces inherited assumptions sometimes. It's not systematic.

      Your split is going in the log this week. Fixed constraint, current default, or rejected-on-assumptions, with the assumption written down. Thanks for this one.