Minimal Bun + TypeScript coding agent with an autonomous 8-hour self-evolution harness.
- LLM-driven coding agent (
OpenAI) with tool calling. - OpenAI integration uses the Responses API (
/v1/responses) for codex-compatible models. - Tooling for URL fetch, Perplexity web search, Hacker News signals, workspace file ops, and Sprites remote build execution.
- Skill loader for
.agents/skills/**/SKILL.md. - Autonomous evolve cycle that:
- observes (issues, commits, journal, optional HN),
- orients,
- chooses one bounded high-impact change,
- implements + validates,
- commits if green,
- reverts if red,
- journals outcome.
Detailed schema for JOURNAL.md entries and the process for evolving it are recorded in docs/journal-schema.md so future cycles can emit and validate entries consistently.
- Bun
>=1.3 - Git + GitHub CLI (
gh) authenticated - OpenAI API key
- Optional: Perplexity API key
- Optional: Sprites CLI for compile-heavy remote runs
bun installCreate env file (or export variables):
export OPENAI_API_KEY=...
export OPENAI_MODEL=gpt-5.1-codex-mini
export PERPLEXITY_API_KEY=... # optional, enables web_search tool
export SPRITES_ENABLED=false # set true to enable Sprites policy
export SPRITES_DEFAULT_NAME=qbuild# Run agent
bun run agent -- "test task: summarize repository architecture"
# Run evolve cycle (plan only)
bun run evolve:cycle --dry-run
# Run evolve cycle (real)
bun run evolve:cycle
# Lint / tests
bun run lint
bun test# check CLI
sprite --help
# wrapper examples
.agents/skills/sprites/scripts/sprites.sh create qbuild
.agents/skills/sprites/scripts/sprites.sh exec qbuild "bash -lc 'uname -a'"
.agents/skills/sprites/scripts/sprites.sh api-get qbuild "/workspace/README.md"
.agents/skills/sprites/scripts/sprites.sh destroy qbuild
# ephemeral build workflow
.agents/skills/sprites/scripts/sprites.sh ephemeral qbuild "bun run lint && bun test"If Sprites is unavailable and SPRITES_ENABLED=true, fractal fails safely with actionable setup errors.
Loaded from .agents/skills/**/SKILL.md:
hackernewsweb-searchspritesdialectic
- File:
.github/workflows/evolve.yml - Triggers:
schedule: every 8 hours (0 */8 * * *)workflow_dispatch: manual run
- Permissions:
contents: writeissues: writepull-requests: write
- Uses:
OPENAI_API_KEY(required)PERPLEXITY_API_KEY(optional)SPRITE_TOKEN(required only whenSPRITES_ENABLED=true)
Workflow behavior:
- Runs
bun run evolve:cycle. - Persists
JOURNAL.mdeven when evolve fails/reverts, then pushes if ahead. - Fails workflow when evolve run reverts due to implementation error.
- Explicit
planoutcomes remain non-error even when they produce no diff. - High-uncertainty cases are recorded as planned handoffs, not a separate outcome.
- Implement runs that produce no diff still fail; only explicit planned handoffs are green.
Set these repository settings:
# required when using sprites
gh secret set SPRITE_TOKEN --repo ghillb/fractal
# enable sprites policy in evolve
gh variable set SPRITES_ENABLED --body \"true\" --repo ghillb/fractal
gh variable set SPRITES_DEFAULT_NAME --body \"qbuild\" --repo ghillb/fractalThe workflow installs Sprite CLI, runs sprite auth setup --token "$SPRITE_TOKEN", then enables compile-heavy remote checks.
$ bun run agent -- "test task: summarize repository architecture"
fractal is organized into src/agent (LLM loop), src/tools (tool adapters), src/skills (SKILL loader), and src/evolve (autonomous cycle).
$ bun run evolve:cycle --dry-run
{
"mode": "dry-run",
"goal": "Become an entity that is ever more capable while improving safely.",
"decision": {
"diagnosis": "...",
"chosenChange": "...",
"rationale": "...",
"uncertainty": 0.32,
"executionMode": "implement",
"compileHeavy": false,
"targetFiles": ["src/evolve/journal.ts"],
"nextCyclePlan": [],
"followUps": ["..."]
}
}
When SPRITES_ENABLED=true and change is compile-heavy, evolve enforces remote validation:
- chosen_change: add Rust build check
- compile_heavy: true
- action: .agents/skills/sprites/scripts/sprites.sh ephemeral qbuild "bun run lint && bun test"
- result: pass -> commit evolve(agent): ...