October 7, 2026
pocketestimator.pro is a quoting tool for independent contractors: describe the job or build it line-by-line from a materials catalog, get a branded estimate, send a link the client approves or declines from their phone. It's the web rebirth of a much older product — and this time nobody wrote it. A LiveGraph bootstrap run created the repo, provisioned Railway, Postgres, and Cloudflare, deployed a self-hosted CI runner, and seeded an eighteen-item QUEUE.md. Then the improvement loop spent a day working it.
Total model spend across fourteen merged pull requests: $12.70 — $18.13 all-in once failed rounds, publish lanes, and the repair graph count too. As usual with these posts, the interesting part is where it broke.
Everything the build touched went through a connector — the model called the connector, the keys never left the encrypted credential store:

A ten-minute tick works QUEUE.md top to bottom — one branch per item, every push runs CI on a self-hosted Railway runner (GitHub Actions minutes had already been exhausted elsewhere), a reviewer reads the diff, and protected paths park at a human gate. Day one's haul:
| Shipped | PR | Spend |
|---|---|---|
| Plan config + landing, estimate schema, CRUD API, builder UI | #3, #4, #6, #7 | $4.72 |
| Catalog library, company profile, public estimate page | #12, #13, #14 | $2.78 |
| AI estimate drafts, decision plumbing fixes | #9, #11 | $1.26 |
| Status page, agent-discovery surface, LiveGraph attribution, CI screenshots | #1, #2, #8, #10 | $3.64 |
| Dockerless CI — the starter's own pipeline, rewritten for the self-hosted runner | #5 | — |
Every merge carries a loop report in docs/loop-reports/ and a ledger row on the history branch — the paper trail is part of the build, not an afterthought.
Mid-afternoon the work-in-progress gate closed on purpose. The plan rename in q-0001 (starter → free/pro/business) had left stale test assertions scattered across four in-flight branches; each had burned its two fix-recovery rounds, and the gate's answer is deliberately not to keep grinding — it's a needs-you flag. A human merged main into each branch, fixed eleven stale assertions, repaired a schema that had silently regressed to the starter's old shape, and pushed. The gate reopened, all four branches merged, and the queue resumed on the next tick. The stall logic — cap recovery, surface the reason, wait — is the same logic that makes the loop safe to run unattended.
The day's best bug surfaced through the MCP registry: its publish flow fetches https://pocketestimator.pro/.well-known/mcp-registry-auth server-side and follows no redirects — and the apex was 301'ing it to www. Chasing that uncovered something worse: every apex path was redirecting to https://www.pocketestimator.pro${http.request.uri.path}/ — literally, braces and all, an unresolvable hostname. The apex had been dead for all visitors, not just the registry. The full-apex outage ran about an hour — the faulty ruleset appeared during the repair pass and the fix landed ~52 minutes later. The proof path itself had been 301'ing since bootstrap's page rules went in — nearly a full day, unnoticed only because nothing had fetched it until the registry tried.
Two config faults: a redirect ruleset rule whose target was stored as a static value instead of a Cloudflare expression, and a page rule whose “.well-known shield” couldn't shield anything because Cloudflare page rules stopped being first-match-only. A repair graph enumerated the zone, and two PATCH calls later the apex served the proof record directly — then published pro.pocketestimator/[email protected] to the official MCP registry on the next pass. Both root causes are queued as platform fixes (q-0140, q-0141) so the next bootstrap never produces this zone shape.

The registry listing isn't decorative — the app is a real MCP server. POST /api/mcp (aliased /.well-known/mcp) speaks JSON-RPC: initialize, ping, tools/list, tools/call. Anonymous callers get an empty public tool list — the ops surface only advertises to a bearer the bootstrap minted and stored in LiveGraph's encrypted secrets, so the owner's graphs can call analytics_summary (last-24-hour API/event/pageview totals) and contact_inbox without the plaintext key ever leaving the vault. Around the endpoint sits the discovery surface q-0016 shipped on day one: an A2A agent card, a Smithery-format server card, agents.txt, llms.txt, a generated openapi.json, and per-AI-bot robots.txt groups — another agent can find, describe, and call this app with no hand-written connector.
The loop ran through the same plumbing to build it: the GitHub MCP for branches, pushes, and pulls; Railway and Cloudflare http_request endpoints for provisioning and the PATCH surgery above; the UX probe for eyes. The registry publish tool was the last connector in the chain — it put the app on the same shelf the loop reached into all day.
Asked whether the build produced any visual evidence, the honest answer was no — so a queue line went in, and the loop implemented it: a Playwright spec that captures the public surfaces at desktop and phone widths, uploaded as a ui-screenshots artifact on every CI run, pass or fail. The images in this post came from that artifact, not a hand held over the keyboard. The same pass registered the site with the UX probe — a text-only accessibility/contrast auditor the deploy-verify gate now runs on every merge.
A day after this post the loop's OpenRouter credit ran dry mid-queue — the paid legs stopped, five pull requests sat green-or-nearly in the publish lane, and the only way forward was a human driving the merges by hand. So we did. The last five items shipped for $0 of model spend:
| Shipped | PR |
|---|---|
| Real estimate PDFs via DreamPDF (template fill over MCP), HTML fallback intact | #23 |
| Authenticated product screenshots — real signup + mailbox-verify flow, committed PNGs | #24 |
| Product ungated — free plan opens every feature; entitlement machinery kept intact for re-gating | #25 |
| Public /tools pages — all four calculators anonymous, sitemap + llms.txt wired, CTA into signup | #27 |
| Abuse guardrails — per-IP and per-user rate limits on the public, AI-draft, and email paths | #28 |
The publish-lane audit found the day's second-best bug, and it nearly shipped: the screenshots branch had gone stale enough that its diff silently reverted merged work — it deleted the DreamPDF client the previous PR had just landed, rolled back a WCAG contrast fix, dropped a sitemap entry and the IndexNow key, and touched the protected queue file. Merged as-is, it would have un-shipped three features while looking green. Realigning every non-payload file to main left a diff of exactly the spec, four PNGs, and a landing-page section. The lesson generalized: a green check on a long-stale branch is a verdict on the branch, not on the merge.
While the credit was out the same pattern got fixed at the source on LiveGraph itself: claimed-but-reportless branches now resume instead of stranding, fully-claimed queues emit an explicit gate reason, and the loop renders a rolling seven-day cost-per-shipped-item and a projected drain cost — so the next “we're out of credit” shows up on the dashboard before it shows up as silence (#316–#318).
The engineering queue is empty — twenty-eight merged pull requests, every line ticked. Even the Android-readiness item shipped along the way (PWA manifest, assetlinks for a TWA wrapper, a bearer-token path on the REST surface — the app is Play-Store wrappable without another code change). What's left isn't queue-shaped: whether the product earns the native shell, offline job-site drafts, and push notifications is a usage question, not a mechanical one. The growth tick still runs Mondays for the submit kits.
Day two's real addition to the manual: a queue can be fully drained and still need the publish lane watched — the loop wrote the last five items, but merging them was the part a human had to do.
The takeaway isn't that a loop can write a quoting app — it's that the failures stayed legible the whole way: a stalled gate that said why, an apex outage that read as a registry-auth error until someone traced it, and a platform queue that absorbed both root causes. Pocket Estimator is live — send a quote they can approve before lunch.