I make AI less about chatting and more about doing.
I am an entrepreneur, builder, and recovering tab-hoarder currently building and learning in public. Each week I sift the AI-verse by actually doing — and send back signals: from what the vibe coders are shipping, and what it unlocks for whatever you're building.
Same story as the Verge AI feed: Altman, Amodei, Hassabis, and Musk agreed to slow AI development; critics question whether it's a safety pact or a cartel move.
learnedA tool that reports success can still have done nothing.I wired Google's CLI into my research step and it came back saying SUCCESS with an empty answer, twice, for two different reasons. Once a permission was silently denied, once it ran out of time mid-thought. If I had trusted the status field I would have built a design on nothing. Now every call passes a gate that checks the answer is actually there.
learnedThree weeks of green tests while the pipeline quietly produced nothingMy content engine reported success every ten minutes for three weeks and shipped nothing. The queue query fetched the ten oldest jobs, all already done, so new work was never picked up. Slack was handed a bare video link it never renders, so finished videos sat unseen. A browser upgrade removed the binary one job needed. Every one of those failures looked exactly like a quiet day. Tests passing tells you the code does what you wrote, not that the system is doing anything at all.
learnedForty-five profitable days that proved nothingMy trading bot has been profitable for 45 days, and that told me almost nothing. All seven of its cycles were the same trade into a market that only went up, so the leg that actually loses money has never once run. I was reading a number as validation when it was really just a rising market.
learnedMy deploy had been broken for two weeks and nothing told me.A cron job pulls my code onto a server every ten minutes. Someone changed how it authenticates, the pull started failing, and the job carried on running the old code perfectly happily. No error anywhere I'd look, because a thing that fails quietly and keeps working looks identical to a thing that's fine.
I only found it because I went to deploy something. Two weeks of "working" that wasn't.
learnedMy portfolio tool reported ten broken projects. It was one expired token, and my own error handler had mislabelled it.Vercel answers an expired token with a 403, not a 401. My adapter read 403 as "you don't have access to this project" and printed that ten times. I spent the morning investigating ten permission problems that did not exist. The tool wasn't lying about the data. It was confidently wrong about the cause, which is worse.
The robot spine behind this site. An agentic content pipeline that drafts, scrubs and ships posts across channels — so the newsletter and the socials keep moving while I build.
the-forgeThe Forge: ✅✅ ARTICLE OUTPUT-QUALITY GATE SHIPPED + LIVE 2026-09-08 (the 08-25 attack call, CLOSED).active
✅✅ ARTICLE OUTPUT-QUALITY GATE SHIPPED + LIVE 2026-09-08 (the 08-25 attack call, CLOSED). src/lib/article/rubric.ts defines 'good'; quality.ts enforces it; the publish route REFUSES on failure. Commit `602beb5` on main, DEPLOYED to the VPS and SHA-verified live (forge.steven-murray.com). 288 tests, mutation-verified twice (before and after a simplifier pass).
GATE, structural layer (deterministic + free): word floor 400, position-template-as-headings, banned engineering vocab, private-field leakage, reading grade ≤12, very-hard-sentence ratio ≤20%. Runs FIRST so obviously-broken prose never costs a model call.
GATE, judged layer: a judge scores VOICE/STRUCTURE/ARGUMENT 1-5, each with its own minimum. A FLOOR not an average — two 5s do not buy off one 2. Unparseable judge = 502, never a pass. Override via POST {override_reason} (10+ chars), logged + returned as quality_override so 'shipped anyway' never reads as 'passed'.
ARTICLE OUTPUT QUALITY is the live problem (Steven 2026-07-27: 'the article output was poor'). Content v2 A/B/C are all SHIPPED and every SDD task passed review — but NO task in the spec ever measured whether the essay is GOOD. The ledger graded 'does the rewriter route return 200', not the writing. Fix the generation quality (voice, structure, argument), not the plumbing.
Spec-design lesson to carry elsewhere: for any generative feature, put an explicit output-quality gate in the plan (a human accept/reject on real output, like signal-layer's persona acceptance rounds) or the ledger will report COMPLETE on bad output.
Still open behind that: SSO v2 (share os_session across subdomains; gateAuth.verifySessionValue is the swap seam) · first REAL position publish
the-forgeThe Forge: ✅✅ ARTICLE OUTPUT-QUALITY GATE SHIPPED + LIVE 2026-09-08 (the 08-25 attack call, CLOSED).active
✅✅ ARTICLE OUTPUT-QUALITY GATE SHIPPED + LIVE 2026-09-08 (the 08-25 attack call, CLOSED). src/lib/article/rubric.ts defines 'good'; quality.ts enforces it; the publish route REFUSES on failure. Commit `602beb5` on main, DEPLOYED to the VPS and SHA-verified live (forge.steven-murray.com). 288 tests, mutation-verified twice (before and after a simplifier pass).
GATE SHAPE: structural layer (deterministic, free — word floor 400, position-template-as-headings, banned engineering vocab, private-field leakage, reading grade ≤12, very-hard-sentence ratio ≤20%) runs FIRST so broken prose costs no model call; then a judge scores VOICE/STRUCTURE/ARGUMENT 1-5, each with its own minimum. A FLOOR not an average — two 5s do not buy off one 2. Unparseable judge = 502, never a pass. Override via POST {override_reason} (10+ chars), logged + returned as quality_override so 'shipped anyway' never reads as 'passed'.
ARTICLE OUTPUT QUALITY is the live problem (Steven 2026-07-27: 'the article output was poor'). Content v2 A/B/C are all SHIPPED and every SDD task passed review — but NO task in the spec ever measured whether the essay is GOOD. The ledger graded 'does the rewriter route return 200', not the writing. Fix the generation quality (voice, structure, argument), not the plumbing.
Spec-design lesson to carry elsewhere: for any generative feature, put an explicit output-quality gate in the plan (a human accept/reject on real output, like signal-layer's persona acceptance rounds) or the ledger will report COMPLETE on bad output.
Still open behind that: SSO v2 (share os_session across subdomains; gateAuth.verifySessionValue is the swap seam) · first REAL position publish
hybrid-aHybrid Athleticism: ✅✅ CHECK-IN/READINESS LOOP SHIPPED + LIVE IN PROD 2026-09-08 (the 08-25 attack call,…active
✅✅ CHECK-IN/READINESS LOOP SHIPPED + LIVE IN PROD 2026-09-08 (the 08-25 attack call, CLOSED). Commit `29f64f0` on main; Vercel production deploy Ready and verified (hybrid-athleticism.vercel.app; /dashboard/check-in returns 307 to login = route exists + auth-gated). 476 tests, `next build` clean, simplifier pass applied, zero new type errors.
⚠ IT WAS WORSE THAN RECORDED: not just submitSelfReport — checkAndTriggerCheckIn, submitSelfReport AND runCheckInCycle all had ZERO callers. The whole subsystem was dead. All 14 check_in_windows sat at status='open' (never once 'triggered'), getReadiness could only ever return UNKNOWN, and runCheckInCycle ran on neutral fallbacks — pinning ~35% of the recovery weighting (sleep/energy/stress/motivation/soreness) to a constant 3.
🐛 REAL BUG FOUND + FIXED 2026-09-08 (pre-existing, predates the wiring): checkAndTriggerCheckIn counted completed sessions with `.not('completed_at','is',null)`, violating the repo's OWN CLAUDE.md gotcha (completed_at only stamped from 2026-07-26). Live data: 46 of 53 rows with status='completed' have a NULL completed_at, so it counted 7 of 53 — 12 of 14 windows saw ZERO completions. That understated `completed`, inflated `missed_sessions`, biased recovery toward false RED, and made the 'all allocated sessions completed' trigger essentially unreachable. Now `.eq('status','completed')`: 53 counted, and week 2 hits 8/8 so condition 1 can finally fire.
BUILD SHAPE: /dashboard/check-in (form) → completeWeeklyCheckIn = submitSelfReport → checkAndTriggerCheckIn → runCheckInCycle IN THAT ORDER (the trigger writes total_completed/missed_sessions/early_completion, which the cycle then reads as the performance half of the same score). getDueCheckIn is READ-ONLY on purpose — the dashboard asks during render, and a render must never advance the coaching cycle. Scheduling rule extracted pure to src/lib/check-in/trigger.ts (8 unit tests incl. window boundary + the totalAllocated=0 trap).
WATCH next week/block generation for conditioning variety (07-26 fix): rotation warning appears in logs if the format repeats; Block 5 strategy must come out intent-only (no example workouts)
VISUAL VERIFICATION CLOSED 2026-07-27 (Steven: 'surfaces are good') — logger %TM+AMRAP badge, session-close summary, rebased week view all confirmed. No visual debt outstanding.
NEXT UP (spec review 07-27): the endurance-domain-wiring plan is FEATURE COMPLETE and merged (0e90d58). The remaining backlog below is unspecced follow-on work — pick the check-in/readiness loop first: it is the only item with dead code already shipped (submitSelfReport has zero callers, athlete_self_reports has 0 rows), so it is half-built and invisible.
Commentary lifecycle still unfixed: coach_notes copied generation → inventory → workout with no owner or clearing step; regeneration leaves stale notes
Close-block nudge may fire early from 2026-08-10 (mesocycles.end_date is GENERATED, can't move with a rebase) — key it off all-sessions-resolved instead
nextSetRecommendation → WorkoutLogger (~10 lines; delta already computed and rendered)
Garmin OAuth re-pair (token paste or CSV fallback)
Possible polish: stale-sessions banner shows date range not just 'week 1'; 'log it late' path from stale modal (backdate exists but no launch UI for past-week workouts)
the-forgeThe Forge: ✅ ARTICLE OUTPUT-QUALITY GATE BUILT 2026-09-07 (the 08-25 attack call, closed).active
✅ ARTICLE OUTPUT-QUALITY GATE BUILT 2026-09-07 (the 08-25 attack call, closed). src/lib/article/rubric.ts defines 'good'; quality.ts enforces it; the publish route REFUSES on failure. NOT COMMITTED, NOT DEPLOYED — 288 tests green, lint clean, no new type errors, awaiting Steven's word to commit+deploy (./deploy/deploy.sh needs a push first).
GATE SHAPE: structural layer (deterministic, free — word floor 400, position-template-as-headings, banned engineering vocab, private-field leakage, reading grade ≤12, very-hard-sentence ratio ≤20%) runs FIRST so broken prose costs no model call; then a judge scores VOICE/STRUCTURE/ARGUMENT 1-5, each with its own minimum. A FLOOR not an average — two 5s do not buy off one 2. Unparseable judge = 502, never a pass. Override via POST {override_reason} (10+ chars), logged + returned as quality_override so 'shipped anyway' never reads as 'passed'.
ARTICLE OUTPUT QUALITY is the live problem (Steven 2026-07-27: 'the article output was poor'). Content v2 A/B/C are all SHIPPED and every SDD task passed review — but NO task in the spec ever measured whether the essay is GOOD. The ledger graded 'does the rewriter route return 200', not the writing. Fix the generation quality (voice, structure, argument), not the plumbing.
Spec-design lesson to carry elsewhere: for any generative feature, put an explicit output-quality gate in the plan (a human accept/reject on real output, like signal-layer's persona acceptance rounds) or the ledger will report COMPLETE on bad output.
Still open behind that: SSO v2 (share os_session across subdomains; gateAuth.verifySessionValue is the swap seam) · first REAL position publish
hybrid-aHybrid Athleticism: ✅ CHECK-IN/READINESS LOOP WIRED 2026-09-07 (the 08-25 attack call, closed).active
✅ CHECK-IN/READINESS LOOP WIRED 2026-09-07 (the 08-25 attack call, closed). NOT COMMITTED — 476 tests green (+8), lint clean, `next build` OK, zero new type errors. Awaiting Steven's word to commit+push (push to main auto-deploys via Vercel).
⚠ IT WAS WORSE THAN RECORDED: not just submitSelfReport — checkAndTriggerCheckIn, submitSelfReport AND runCheckInCycle all had ZERO callers. The whole subsystem was dead. All 14 check_in_windows sat at status='open' (never once 'triggered'), getReadiness could only ever return UNKNOWN, and runCheckInCycle ran on neutral fallbacks — pinning ~35% of the recovery weighting (sleep/energy/stress/motivation/soreness) to a constant 3.
BUILD SHAPE: /dashboard/check-in (form) → completeWeeklyCheckIn = submitSelfReport → checkAndTriggerCheckIn → runCheckInCycle IN THAT ORDER (the trigger writes total_completed/missed_sessions/early_completion, which the cycle then reads as the performance half of the same score). getDueCheckIn is READ-ONLY on purpose — the dashboard asks during render, and a render must never advance the coaching cycle. Scheduling rule extracted pure to src/lib/check-in/trigger.ts (8 unit tests incl. window boundary + the totalAllocated=0 trap).
WATCH next week/block generation for conditioning variety (07-26 fix): rotation warning appears in logs if the format repeats; Block 5 strategy must come out intent-only (no example workouts)
VISUAL VERIFICATION CLOSED 2026-07-27 (Steven: 'surfaces are good') — logger %TM+AMRAP badge, session-close summary, rebased week view all confirmed. No visual debt outstanding.
NEXT UP (spec review 07-27): the endurance-domain-wiring plan is FEATURE COMPLETE and merged (0e90d58). The remaining backlog below is unspecced follow-on work — pick the check-in/readiness loop first: it is the only item with dead code already shipped (submitSelfReport has zero callers, athlete_self_reports has 0 rows), so it is half-built and invisible.
Commentary lifecycle still unfixed: coach_notes copied generation → inventory → workout with no owner or clearing step; regeneration leaves stale notes
Close-block nudge may fire early from 2026-08-10 (mesocycles.end_date is GENERATED, can't move with a rebase) — key it off all-sessions-resolved instead
nextSetRecommendation → WorkoutLogger (~10 lines; delta already computed and rendered)
Garmin OAuth re-pair (token paste or CSV fallback)
Possible polish: stale-sessions banner shows date range not just 'week 1'; 'log it late' path from stale modal (backdate exists but no launch UI for past-week workouts)
personal-osSteven Personal OS: ▶ ARTICLES SECTION is the live build need (07-09).active
▶ ARTICLES SECTION is the live build need (07-09). Build a real Articles section — index/listing + reading template + nav, stronger styling (the 'Article Studio' need). A one-off route at /content/articles/the-build-got-cheap was REJECTED by Steven: styling weak, and articles need their own section.
Article #1 body is APPROVED at `drafts/articles/2026-07-09-the-build-got-cheap.md` (AI makes ALIGNMENT cheap, not just building; spec-as-bible; scope-creep-when-cheap; north-star-holds). Publish once the section exists: add an `os_signals` row `channel='article'` + prod.
Uncommitted WIP on disk for that article — the route, `Artwork.tsx` (convergence-field hero + wave), `PhasesLoop.tsx`, anonymised fragments under `public/media/articles/build-got-cheap/`. Salvage or rebuild.
▶ SIXTY4SIXTY is the monetisation answer and is BUILDING (2026-08-14). Tracker LIVE at https://sixty4sixty.vercel.app/tracker.html; domain attached. Detail: [[project_sixty4sixty]]
SIXTY4SIXTY — Steven owes DNS at GoDaddy: CNAME `sixty4sixty` -> `cname.vercel-dns.com`. ⚠ Do NOT touch the apex A or the www CNAME.
SIXTY4SIXTY — Steven owes the start date, or the 06:30 morning-nudge timer cannot compute the day number; it is written but NOT installed without it.
SIXTY4SIXTY — the 3-day manual pilot GATES all further build. Run it before writing more code.
NEWSLETTER SEQUENCING IS AN OPEN CALL. Spec `2026-07-24-newsletter-launch-design.md` Phase 2 does DAILY radar first, WEEKLY second. Recommendation on the table, unanswered: invert it — the weekly (curated best-of + Steven's take) is the differentiated product, ships to a list of one, needs no per-subscriber batching.
⚠ Real subscriber count is ZERO — the single row is a bot signup. Judge any monetisation or newsletter plan against that. The highest-leverage growth action (point 7,775 LinkedIn followers at the signup) currently sits LAST in the sequence, behind a product that cannot send.
Newsletter: Steven to click the confirm link and check inbox-vs-spam. Double-opt-in is E2E verified but first-send placement is unproven — the root domain carries a GoDaddy DMARC `p=reject`.
⚠ DMARC `rua=` points at GoDaddy's address, not Steven's, so he receives NO failure reports.
⚠ Resend free tier is 3,000/mo and 100/day — a daily mailer to a real list breaks that.
~/newsletter
One AI signal newsletter a week. Zero hype, mostly.
What the vibe coders are building and what AI is unlocking for builders and operators. Written for people who ship.