AWS Flywheel

Autonomous multi-branch release engine — 3 bug + 1 UX fix per branch, every hour, via AI-first multi-provider fallback chain with rotating pool safety net. Self-learning, self-healing, cross-branch daily dedup.

21 branches 24h cooldown 1 release/hour 303 releases 6 AI providers

Source: github.com/unclehowell/datro/tree/cnei/flywheel

Workflow

A cron job (0 * * * *) on an AWS EC2 instance (1 vCPU, 1 GB RAM) runs the flywheel once per hour. Each run produces exactly one release for one branch — 3 unique bug fixes + 1 novel UX feature — across 21 Cloudflare-deployed websites.

⏰ Cron HH:00
Lockfile checkExit if locked
Sync timestamps from GitHub
Select branchRound-robin rotation_index → cooldown check
↓ all on cooldown?Sleep until nearest eligible
Git checkout branchgit reset --hard origin/BRANCH
4 Fix Passes
Pass 1 Bug Fix #1 AI-first · Pool fallback
financecheque proxy → empty? child proxy (kilo) → fail? OpenRouter → fail? Gemini → fail? DeepSeek → fail? Groq → all empty? Pool (8 functions)
Pass 2 Bug Fix #2 AI-first (with daily-fixes blacklist) · Pool fallback
financecheque proxy → empty? child proxy (kilo) → fail? OpenRouter → fail? Gemini → fail? DeepSeek → fail? Groq → all empty? Pool (next rotation)
Pass 3 Bug Fix #3 AI-first · Pool fallback · Guaranteed fallback (last resort)
financecheque proxy → empty? OpenRouter → Gemini → DeepSeek → Groq → all empty? Pool → Guaranteed fallback
Pass 4 UX Feature AI-first · Pool (23 UX functions)
financecheque proxy → empty? OpenRouter → Gemini → DeepSeek → Groq → all empty? UX Pool (23 functions)
↓ all passes doneGit commit all changes
Create tag {branch}-v0.0.{N/100}.{N%100:02d}
Generate blog post & RSS
Push branch + tag to GitHub
Create GitHub Release with structured notes
Verify release live (5 retries)
Verify Cloudflare deploy (5 retries)
Prune old releases (keep last 3)
✓ Release complete

AI Provider Fallback Chain

Each pass attempts AI first. The intelligence.py agent cycles through providers in order until one returns a valid JSON fix:

OrderProviderTypeTimeoutKeys
1financecheque.uk proxyParent proxy → routes to child proxy70s (3 retries)
2172.31.29.216:4001Child proxy → runs kilo CLI15s
3OpenRouterDirect API (gpt-4o-mini)90s
4GeminiDirect API (gemini-2.0-flash)90s
5DeepSeekDirect API (deepseek-chat)90s
6GroqDirect API (llama-3.3-70b-versatile)90s

API keys are stored in ~/.fcukproxy/.env (sourced by intelligence.py) and ~/.secrets/.env. All 4 direct API providers now have valid keys.

Key Improvements

🔄 Cross-branch daily dedup: daily-unique.json prevents ANY fix/feature description from repeating across ALL 21 branches in a single UTC day. Each pass passes the growing --daily-fixes / --daily-features list to the AI prompt as "TODAY'S ALREADY-APPLIED" — the AI must produce something novel.
🔁 4 AI-first passes (not 1): Previously only Pass 1 tried AI. Now all 3 bug passes + 1 UX pass attempt AI with growing daily blacklists. Pool is fallback only, guaranteed fallback is last resort on Pass 3 only.
📉 Shrunk pool to real functions: BUG_FIX_NAMES had 37 entries but only 5 real functions existed. Removed 32 phantom "command not found" entries. Now 8 real bug functions + 23 UX functions — all tested and working.
⏱️ Retry + provider fallback: Proxy calls retry 3× with backoff. On empty response, falls through 6 providers before hitting the pool.

Components

FileRole
multi-branch-release.shBash orchestrator — cron entrypoint, branch selection, 4-pass dispatch, git/release, daily tracking, pool functions, cooldown handler
intelligence.pyPython AI agent — builds prompts with file excerpts + master plan todos, rotates through 6 LLM providers, applies fixes, manages profiles, self-learns
.envAPI keys for OpenRouter, Gemini, DeepSeek, Groq — loaded at runtime
release-state.jsonState file — rotation_index, cooldown timestamps, release counters, fix/ux rotation pointers
daily-unique.jsonCross-branch dedup — date + lists of all bug/feature descriptions applied today
profiles.jsonPer-branch profiles — LLM rotation lists, learned patterns, skill libraries, branch knowledge
agent/branches/*.md21 master plans — vision, strategic roadmap, required features, success criteria per branch

21 Branches

BranchDomainReleases
financechequefinancecheque.uk152
ccanccan.datro.xyz18
carfinancechequecar.financecheque.uk15
ceoceo.datro.xyz9
altheaalthea.datro.xyz8
datrodatro.xyz8
dccdcc.datro.xyz8
guigui.datro.xyz8
hbnbhbnb.datro.xyz8
librarylibrary.datro.xyz8
bpvsbucklerbpvsbuckler.datro.xyz7
archivesarchives.datro.xyz7
dashdash.financecheque.uk7
llmwikillmwiki.financecheque.uk7
uiui.datro.xyz7
wavewave.datro.xyz7
subrepossubrepos.datro.xyz6
waybackwayback.datro.xyz6
whitepaperwhitepaper.financecheque.uk3
cneicnei.datro.xyz3
greathousefarmgreathousefarm.datro.xyz1

Total: 303 releases. Each branch deploys via Cloudflare Pages at {branch}.datro.pages.dev with custom domain {branch}.datro.xyz (or *.financecheque.uk).

Pass Strategy Detail

Pass 1 (Bug) — AI-first → Pool

Attempts AI via 6-provider chain. The prompt includes file excerpts (500 chars), master plan TODOs, and "TODAY'S ALREADY-APPLIED" daily blacklist. If all providers return empty, falls to rotating bug pool (8 functions). On pool success, the daily file is updated and the fix rotation advances.

Pass 2 (Bug) — AI-first → Pool

Same as Pass 1 but the daily blacklist now includes the fix from Pass 1. This guarantees the AI (or pool) produces a different fix. Pool starts from where last pass left off (fix_rotation).

Pass 3 (Bug) — AI-first → Pool → Guaranteed fallback

Last bug pass. If AI and pool both fail, the guaranteed_bug_fallback runs: it searches the branch directory for files with 3+ consecutive blank lines and removes them. This always produces a fix.

Pass 4 (UX) — AI-first → UX Pool

User-experience pass. Same AI chain but with --daily-features blacklist. Falls to UX pool (23 functions) then guaranteed_ux_fallback (adds DOCTYPE + charset if missing).

Bug Pool (8 real functions)

FunctionDescription
fix_404_titleSet proper title on 404 pages
fix_doctypeAdd <!DOCTYPE html> if missing
fix_charsetAdd <meta charset="UTF-8"> if missing
fix_lang_attributeAdd lang="en" to HTML tag
fix_privacy_policyCreate privacy policy page
fix_terms_serviceCreate terms of service page
fix_contact_pageCreate contact page with form
fix_blog_launchCreate blog index + welcome post

UX Pool (23 functions)

FunctionDescription
ux_viewportImprove viewport meta with user-scalable=yes
ux_mobile_tapAdd min tap target sizes (44px)
ux_hover_stylesAdd hover opacity transition
ux_css_orderMove CSS before JS in head
ux_skip_linkAdd skip-to-content link
ux_color_contrastImprove text/background contrast
ux_smooth_scrollAdd smooth scrolling behavior
ux_print_stylesAdd print-friendly styles
ux_focus_visibleAdd focus-visible keyboard styles
ux_touch_actionSet touch-action: manipulation
ux_button_statesAdd disabled/active button states
ux_table_responsiveWrap tables in scroll containers
ux_z_indexFix z-index stacking order
ux_list_semanticsFix list nesting semantics
ux_loading_indicatorAdd loading spinner styles
ux_breadcrumbAdd breadcrumb navigation
ux_cls_fixFix cumulative layout shift
ux_type_scaleAdd typographic scale
ux_spacingAdd consistent spacing rhythm
ux_keyboard_navImprove keyboard navigation
ux_cookie_consentAdd cookie consent banner
ux_social_linksAdd social sharing links
ux_footer_legalAdd footer with legal links

Cooldown & Branch Selection

Version Scheme

release_number = total_releases[branch] + 1
patch  = release_number / 100          # increments every 100 releases
build  = release_number % 100          # 0–99, zero-padded
tag    = {branch}-v0.0.{patch}.{build:02d}
        e.g., datro-v0.0.0.08, financecheque-v0.0.1.52

Daily Uniqueness

Stored in agent/daily-unique.json. At UTC midnight the file resets. Each fix/feature recording checks the description against the existing list before appending. The AI prompt includes --daily-fixes and --daily-features as "TODAY'S ALREADY-APPLIED" — forcing the LLM to propose something genuinely new across all 21 branches.

Security Model


Generated by the cnei branch — source · Last update: May 2026 · 303 releases and counting