Sparkspec #1
Three small ideas worth building. Every week.
This week: side projects you have lost track of, agents that retry their way into a big bill, and sharing a growing list of links without handing it to a platform.
Welcome to the first issue. Here is how it works: we read public threads on Hacker News, Reddit and X, keep the complaints that are specific and repeated, and turn three of them into small apps you can build in a day. Every idea links to the thread it came from, so you can read the original words yourself.
A note on "validated": these problems show up in public discussion. That is a signal, not proof of demand or revenue. Talk to the people in the thread before you invest heavily.
Issue #1 is fully open: all three specs and all three prompts are free this week.
Idea 1: Hangar, one file that knows where all your side projects live
The problem
Solo builders ship a lot of small projects across a lot of hosts. Months later they cannot say which project runs where, which ones are still up, or which domains are about to renew for projects they have abandoned. The usual fix is a spreadsheet that goes stale.
Who has it
Indie hackers and vibe coders with 5 to 20 deployed projects spread across Vercel, Render, Railway, Fly.io, a VPS and several registrars.
Evidence
- On r/SideProject, a builder with "like 8-9 side projects deployed across different platforms" lists what they cannot keep track of, including "Which ones are actually still running vs sleeping" and "If something broke (I only find out when someone DMs me "your API is down")", and adds: "Right now I literally have a messy spreadsheet with deployment URLs but it's always out of date." Source: https://www.reddit.com/r/SideProject/comments/1qyf1mx/how_do_you_guys_keep_track_of_all_your_deployed/
- In an Ask HN thread on unfinished projects, one commenter describes "a graveyard of expired domains", another says the start of each calendar year "was always like a sucker punch to the wallet", and a third estimates their own renewals at "at least $1k and yes I have a problem." Source: https://news.ycombinator.com/item?id=49300703
What already exists: Registrar dashboards and multi-registrar domain tools cover domains. Uptime monitors cover health. Self-hosting platforms like Coolify help if you consolidate. The gap is one small, local inventory that joins project, host, health, domain and cost, and tells you what to keep or kill.
One-page spec
User: A solo builder who wants a 60 second weekly answer to "what is running, what is broken, what is about to cost me money, and what should I shut down?"
Core features
- A single
hangar.yamlfile, kept in git, listing projects and domains. hangar check: hits each project's health URL, records status code and latency.- Domain expiry lookup through public RDAP (no registrar API keys needed).
- Local dashboard: up or down, last checked, days until each domain renews, total monthly cost in USD.
- "Keep or kill" flags: a domain renewing within 30 days on a project marked
parkedorabandonedgets highlighted. - Optional alerts to a webhook or a self-hosted ntfy topic when a project goes down or a renewal is near.
Out of scope
- Registrar or hosting provider API integrations.
- Changing auto-renew settings or DNS.
- Scraping free tier usage from host dashboards.
- Accounts, teams, a hosted version.
Data model
Project: id, name, status (active|parked|abandoned), repo_url, host, health_url, domain (optional), monthly_cost_usd, notesDomain: name, registrar, renewal_cost_usd, auto_renew (bool), expires_at (from RDAP, cached)Check: project_id, checked_at, http_status, latency_ms, ok (bool)
Tech suggestion: Bun and TypeScript, a YAML file as the source of truth, SQLite (bun:sqlite) for check history, Hono for a tiny dashboard on localhost. Run checks from cron or a built-in interval. Ships as one binary with bun build --compile.
1 day build plan
- Morning: YAML schema and validation,
hangar checkwith health pings and SQLite history. - Midday: RDAP lookup with caching, renewal math, monthly cost totals.
- Afternoon: dashboard with keep or kill highlighting.
- Evening: webhook and ntfy alerts, README, compile and release.
Vibe coding prompt
Build a local-first CLI and dashboard called Hangar using Bun and TypeScript. No accounts, no cloud backend.
Source of truth:
- A hangar.yaml file in the current directory with two lists: projects and domains.
- Project fields: id, name, status (active | parked | abandoned), repo_url, host (free text like "vercel" or "vps"), health_url, domain (optional, must match a domain name in the domains list), monthly_cost_usd (number), notes.
- Domain fields: name, registrar, renewal_cost_usd, auto_renew (boolean).
- Validate the file with zod and print clear errors with line context. Include a commented example hangar.yaml.
Commands:
- `hangar check`: for every project with a health_url, send a GET with a 10 second timeout. Record checked_at, http_status, latency_ms and ok (2xx or 3xx) in a SQLite database at .hangar/hangar.db using bun:sqlite.
- `hangar domains`: for every domain, look up the expiration date via RDAP using https://rdap.org/domain/<name>, read the "expiration" event, and cache the result in SQLite for 24 hours. Handle lookup failures gracefully and show "unknown".
- `hangar report`: print a table in the terminal with project, host, status, last check result, domain, days until renewal, and monthly cost. Print total monthly cost in USD at the bottom.
- `hangar serve`: start a dashboard on http://localhost:4545 using Hono. Plain HTML and minimal CSS, no frontend framework. Show the same table, red for down, amber for renewals within 30 days.
- `hangar watch --every 15m`: run check on an interval.
Keep or kill:
- Highlight any domain renewing within 30 days that belongs to a project with status parked or abandoned, with the label "Renewal soon on an inactive project".
Alerts (optional):
- If ALERT_WEBHOOK_URL is set, POST JSON when a project changes from ok to down, and when a domain is 14 days or less from renewal (once per day max).
- If NTFY_URL is set, send the same alerts as plain text to that ntfy topic.
Add tests for YAML validation and renewal date math. Write a README with install, example config, and how to run checks from cron. Build a single binary with `bun build --compile`.
Idea 2: Tripwire, a circuit breaker for agents that will not stop retrying
The problem
People running their own agents with their own API keys see the bill jump, but provider dashboards only show totals. They cannot tell which agent or task caused it, and they have no way to automatically cut off a task that is stuck in a retry loop.
Who has it
AI agent tinkerers running multi-agent research or coding scripts against OpenAI-compatible APIs, often unattended.
Evidence
- An Ask HN post titled "How are you keeping AI coding agents from burning money?" opens with: "My agents retry a bit more than it should, and there goes my bill up in the sky." It continues: "everything shows up as aggregate usage. Total tokens, total cost, maybe per model." Later in the thread the author clarifies: "my issue wasn't just inefficiency, it was agents retrying when they shouldn't. I needed visibility + limits per agent/task, and the ability to cut it off, not just optimize it." Source: https://news.ycombinator.com/item?id=47559293
What already exists: The thread mentions a few early tools (including a self-hosted per-route cost tracker), and LLM gateways offer budgets. The small, open, local-first wedge is loop detection: notice when a task keeps sending the same request and trip a breaker before the bill grows.
One-page spec
User: A developer running agents locally or on a small server who wants per-task cost visibility and an automatic stop when a task loops.
Core features
- Local OpenAI-compatible proxy. Point
base_urlat it, keep your own key. - Every request is tagged with an agent and a task via headers (defaults if missing).
- Per-task limits: max USD, max requests, max tokens.
- Loop detection: if the same normalized request (model plus last few messages) repeats N times within a time window, the task trips.
- Error storm detection: N consecutive upstream errors trips the task.
- Tripped tasks get HTTP 429 with a clear JSON reason. Reset or kill a task from the CLI or dashboard.
- Dashboard: cost per agent and per task, tripped tasks with reasons, last 100 requests.
Out of scope
- Billing reconciliation with provider invoices.
- Model routing or prompt optimization.
- Multi-user auth, hosted service.
- Non-OpenAI-compatible APIs in v1.
Data model
Task: agent, task_id, state (open|tripped|killed), tripped_reason, max_usd, max_requests, max_tokens, created_atRequest: id, ts, agent, task_id, model, request_hash, prompt_tokens, completion_tokens, cost_usd, upstream_status, blocked (bool)Prices(config file): model, input_usd_per_million, output_usd_per_million
Tech suggestion: Go for a single static binary: net/http reverse proxy, SQLite via modernc.org/sqlite (no CGO), YAML config, a server-rendered dashboard with html/template. Runs on localhost or a $5 VPS.
1 day build plan
- Morning: pass-through proxy for chat completions, streaming and non-streaming, header tagging.
- Midday: token and cost logging, per-task limits.
- Afternoon: request hashing, loop and error storm detection, 429 responses, reset and kill commands.
- Evening: dashboard, README with examples for common SDKs.
Vibe coding prompt
Build a local proxy called Tripwire in Go. It must compile to a single static binary with no CGO.
Proxy:
- Listen on 127.0.0.1:8788 and expose an OpenAI-compatible POST /v1/chat/completions endpoint.
- Forward requests to the upstream base URL set in tripwire.yaml, passing through the Authorization header unchanged. Tripwire never stores API keys.
- Support streaming (SSE) and non-streaming responses. For streaming, inject stream_options.include_usage=true if the client did not set it, and read usage from the final chunk.
- Tag each request with agent and task from the X-Tripwire-Agent and X-Tripwire-Task headers. Default both to "default".
Accounting:
- Store tasks and requests in SQLite using modernc.org/sqlite.
- Request row: id, ts, agent, task_id, model, request_hash, prompt_tokens, completion_tokens, cost_usd, upstream_status, blocked.
- Compute cost_usd from a price table in tripwire.yaml (USD per million input and output tokens per model).
Limits and breakers (all configurable in tripwire.yaml, with per-task overrides via X-Tripwire-Max-USD and X-Tripwire-Max-Requests headers on the first request of a task):
- max_usd, max_requests and max_tokens per task.
- Loop detection: request_hash is a SHA-256 of the model plus the last 3 messages with whitespace normalized. If the same hash appears loop_threshold times (default 4) within loop_window (default 10 minutes) for one task, set the task state to tripped with reason "loop".
- Error storm: if error_threshold (default 5) consecutive upstream responses for a task are 4xx or 5xx, trip with reason "error_storm".
- When a task is tripped or killed, do not forward. Return HTTP 429 with JSON: {"error":{"type":"tripwire","reason":"...","agent":"...","task":"...","spent_usd":...}}.
CLI:
- `tripwire serve`
- `tripwire tasks` prints a table of tasks with state, requests, tokens and spend.
- `tripwire reset <agent>/<task>` and `tripwire kill <agent>/<task>`.
Dashboard:
- Serve at GET / with html/template and minimal CSS. Show spend per agent, spend per task, tripped tasks with reasons and reset buttons, and the last 100 requests.
Include table-driven tests for hashing, loop detection and cost math, an example tripwire.yaml, and a README showing how to point the OpenAI Python and JS SDKs at the proxy by changing base_url and adding the headers.
Idea 3: Linkroll, a growing list of links that people can follow, on files you own
The problem
People want the old social bookmarking experience back: keep adding links to a public or shared list, and let friends follow along as it grows. Today that usually means a platform account, a paid app, or a doc nobody checks.
Who has it
Writers, researchers, curators and self-sovereignty fans who would rather publish from their own repo or server than rent a feed from a platform.
Evidence
- An Ask HN post titled "In 2026, how do you share a list of URLs to the public (or friends)?" asks: "Like del.icio.us in the old days?" and adds: "Ideally, this list of URLs grows. I add new URLs, and others who follow the list can see the updates." The top reply recommends a self-hostable bookmark manager with per-friend lists and RSS. Source: https://news.ycombinator.com/item?id=47353908
What already exists: Full bookmark managers like Karakeep (self-hostable, with RSS for lists) do this and more. Linkroll is the opposite end: no database, no server required, just files in git that build to a static site and feeds. Good for people who want the smallest possible thing they fully own.
One-page spec
User: Someone who wants to add a link in 5 seconds and have it show up on a public page and in an RSS feed their friends already read.
Core features
- Lists stored as plain YAML files in a git repo, one file per list.
linkroll add <url> --list <slug> --note "..." --tags a,b: fetches the page title and description, appends the entry.linkroll build: static HTML page per list, an index of all lists, an RSS 2.0 feed and a JSON Feed per list, and an OPML file of all feeds.- Unlisted lists: published under a random slug and left out of the index (clearly labeled as not private).
- Bookmarklet that sends the current page to
linkroll serve, a tiny local add endpoint. - Deploy anywhere static: GitHub Pages, Cloudflare Pages, or your own server.
Out of scope
- Accounts, comments, likes, follows inside the app (RSS is the follow button).
- Page archiving or full text capture.
- Truly private lists with auth.
- Browser extensions and mobile apps.
Data model
List(lists/<slug>.yamlheader): slug, title, description, visibility (public|unlisted)Link(entries in the list file): id, url, title, description, note, tags[], added_atSite(linkroll.yaml): site_title, base_url, author_name (optional)
Tech suggestion: Node and TypeScript CLI, plain files as the database, a small HTML template, feed npm package or hand-written XML for RSS and JSON Feed. No runtime server in production.
1 day build plan
- Morning: file format,
addcommand with title and description fetching. - Midday: static build for list pages and index.
- Afternoon: RSS, JSON Feed and OPML, unlisted handling.
- Evening: bookmarklet plus local add endpoint, deploy guide, publish to npm.
Vibe coding prompt
Create a Node.js CLI called linkroll, written in TypeScript, that turns plain YAML files into a static link list site with feeds. No database and no production server.
Files:
- linkroll.yaml at the repo root: site_title, base_url, author_name (optional).
- lists/<slug>.yaml per list: slug, title, description, visibility (public | unlisted), and links (array).
- Each link: id (short random id), url, title, description, note, tags (array), added_at (ISO 8601).
- Validate all files with zod and print readable errors.
Commands:
- `linkroll init`: create linkroll.yaml, a lists/ folder with an example list, and a .gitignore.
- `linkroll add <url> --list <slug> [--note "..."] [--tags a,b]`: fetch the URL with a 10 second timeout, read <title>, og:title and og:description (fall back gracefully), and prepend the link to the list file. Reject duplicates within a list.
- `linkroll new-list <slug> [--unlisted]`: create a list. For unlisted lists, append a random 10 character suffix to the published path.
- `linkroll build`: output to dist/:
- index.html listing public lists only.
- One HTML page per list, newest first, with tag filters done in a few lines of vanilla JS.
- feed.xml (RSS 2.0) and feed.json (JSON Feed 1.1) per list, with absolute URLs from base_url.
- lists.opml containing every public list feed.
- Add a visible note on unlisted pages: "Unlisted, not private. Anyone with the link can see it."
- `linkroll serve`: start a local server on 127.0.0.1:4646 with POST /add (url, list, note, tags) that calls the same add logic, plus a page that shows a bookmarklet the user can drag to their bookmarks bar. Only accept requests from localhost.
Styling: clean, readable, plain CSS, dark mode via prefers-color-scheme. No tracking scripts.
Include tests for the file format, duplicate detection and feed output, plus a README covering GitHub Pages and Cloudflare Pages deploys and how friends subscribe via RSS.
Before you build
- Read the source thread first. Reply there if you build something; the people who complained are your first users.
- Ideas are not exclusive. Others may build the same thing. Niche, execution and distribution decide who wins.
- Product names above are working titles. Check for trademark and domain conflicts before you launch.
Get every spec
Sparkspec is free: one email a week with three ideas, plus the first full spec and prompt. Sparkspec Pro is $9 a month for all three specs and prompts every week and the full archive. Cancel anytime. Spec Packs are $19 each: 10 themed specs and prompts, yours to keep.
Know a builder who keeps asking "what should I build?" Send them this page.
Sparkspec. Three small ideas worth building. Every week.