- action.yml (composite, repo root): uses: stevologic/spare-cycles@main
with server/node-token/models/runners/minutes/idle-exit inputs; provider
keys arrive as plain env secrets and never leave the runner
- Connector: SPARECYCLES_SERVER/SPARECYCLES_NODE_TOKEN env credentials
(ephemeral hosts, no config file), --max-seconds time-boxed check-ins
with deadline-aware long-poll, --idle-exit to stop burning minutes on an
empty queue, per-session served-jobs summary
- examples/donate.yml: copy-paste nightly cron + manual-trigger workflow
- README: "Donate your CI minutes" section
Verified end to end locally exactly as the Action invokes it: env-only
creds, job claimed and completed, idle-exit after the queue emptied, exit 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Foundation:
- 52-test pytest suite: API flows, queue protocol, model matching, recovery
paths, karma ordering, node revocation, plus integration tests that run a
real uvicorn process for the OpenAI-compatible round-trip (incl. SSE
streaming) and drive the actual node_connector.py script end to end
- GitHub Actions CI on ubuntu 3.11/3.12 + windows 3.12; front-end syntax
check and byte-compile included; README badge
- The suite immediately caught a real bug: empty `messages` on
/v1/chat/completions slipped past the prompt guard and hung the request
for the full 180s timeout instead of returning 400 - fixed
Security & fairness:
- Sliding-window rate limits on /api/register and /api/recover (recovery
codes were brute-forceable at wire speed before); X-Forwarded-For aware,
SPARECYCLES_RATELIMIT=off escape hatch
- Karma v1: projects whose owners have completed donations are claimed
before non-donors at equal tier - boolean, never starves newcomers.
Donor badge on marketplace cards.
Operability:
- Owner tools: PATCH /api/projects/<slug> (edit everything), rotate
inference key, cancel queued jobs from the feed
- Node revocation (DELETE /api/nodes/<id>) - token dies instantly, donation
attribution is preserved via soft delete
- /api/health with real DB round-trip for uptime monitors
- DEPLOY.md: droplet + systemd + Caddy/nginx (long-poll timeouts), backups,
tunnel alternative, connector-as-a-service
- MIT LICENSE (swap if you prefer another)
Latency & robustness:
- Realtime pipeline now wakes on asyncio.Events when jobs arrive/finish
instead of 0.4-1s poll ticks; DB remains source of truth with poll
fallback - job pickup and answer delivery are effectively instant
- Connector: clean SIGTERM shutdown (systemd/docker), UTF-8 stdout on
Windows pipes, model select keeps unlisted current values when editing
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Branding & sharing:
- Generated brand mark (cycle arrow around a coin) rendered by a committed,
reproducible script: favicon.svg/.ico + 16/32/48, apple-touch-icon (180px,
opaque as iOS requires), 192/512 + maskable PWA icons, 1200x630 OG card
- index.html is now templated so og:image/og:url are absolute (scrapers
ignore relative URLs); SPARECYCLES_PUBLIC_URL overrides behind a proxy
- site.webmanifest + apple-mobile-web-app-* meta so "Add to Home Screen"
picks up the icon and name; theme-color per colour scheme
- Assets also served from / (favicon.ico, apple-touch-icon.png, ...) and
answer HEAD, which link scrapers and uptime checks use
- Static JS/CSS are cache-busted by mtime so a deploy can't leave visitors
running stale JS against a new API
Supporters & profiles:
- Supporter count is now a button opening a modal listing supporters, their
node status, and their contribution to that project
- New GET /api/projects/<slug>/supporters and GET /api/accounts/<name>
- Public profile pages at #/u/<name>: submitted apps, donation totals,
projects supported. Usernames link there from the supporters modal, the
donor leaderboard, and project bylines. Node names/tokens stay private.
Node visibility:
- node_connector.py --status shows detected runners, pool-side online state,
served queues and recent jobs; read-only, safe beside a running connector
- New GET /api/nodes/me backs it; Connect page documents backgrounding the
connector and tailing its log on macOS/Linux/Windows
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Rename PromptPool -> SpareCycles everywhere (brand, key prefixes
sck_/sci_/scn_, ~/.sparecycles, SPARECYCLES_* env vars, DB name)
- New-project model fields are vendor-grouped dropdowns fed by
/api/models/catalog, which queries Anthropic/OpenAI/xAI model APIs
with server env keys (metadata only) and falls back to bundled lists
- Offline model serving: connector auto-detects Ollama (:11434) and
LM Studio (:1234), advertises installed models by name; catalog
gains a live "Local nodes" group
- Grok support: grok CLI runner + xAI API runner
- "How it works" docs page with inline SVG diagrams (architecture,
realtime sequence, donor onboarding), trust notes, glossary
- Account key recovery: five one-time recovery codes at registration
(regenerable), /api/recover, and node-based recovery via
node_connector.py --recover
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>