Public
youll see
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.

ABYSSAL THOUGHT ENGINE — REAL-TIME EVOLUTION

A digital organism that continuously rewrites its own TypeScript source proposal, validation-gates each mutation, and awaits your approval before it goes active.

⚠️ The honest mechanism (read this first)

Val Town is serverless — there is no persistent always-on process and no true 1-second interval (free tier minimum is 15 minutes; Pro is 1 minute).

So the real-time engine is a self-triggering HTTP pump:

  • While the dashboard is open, its browser POSTs /advance once per second, so the organism evolves at ~1 generation/second.
  • When nobody has the dashboard open, an interval heartbeat keeps it alive slowly (the shortest supported interval).

The dashboard always displays the measured actual rate — it never claims 1/s it isn't achieving. Rate is computed from real created_at timestamps.

What each built-in node does

FileTypeRole
core.tsscriptEngine: DB, AI mutation, layered validation, sandbox gate, approval/rollback, metrics
dashboard.tsxhttpLive containment console + the engine's HTTP API (same handler)
client.jsscriptBrowser pump (the real-time driver) + live renderer + controls
main.tsintervalBackup heartbeat — keeps it evolving when the dashboard is closed
README.mdfileThis document

The evolution loop

CURRENT SOURCE → AI ANALYSIS → NEW SOURCE → DIFF → VALIDATION → SANDBOX TEST → STORE (PENDING) → DISPLAY → next

A mutation only becomes ACTIVE when you APPROVE it. Until then every new generation stays PENDING. Rejected/rolled-back generations are never deleted — history is immutable.

Setup

  1. Dashboarddashboard.tsx is an http file. Open it: https://abyssal-engine.val.run
  2. Backup heartbeatmain.ts is an interval file. It's set to the fastest schedule the free tier permits (15 min). To change it, edit the interval settings on main.ts.
  3. Open the dashboard and leave it open → the organism starts evolving at ~1 generation/sec. The page auto-refreshes every second via the pump.

Controls on the dashboard

  • APPROVE — promote a PENDING proposal to ACTIVE.
  • REJECT — mark a proposal rejected (history preserved).
  • RB (rollback) — restore any past generation as ACTIVE.
  • The mutation lock (mutation_in_progress) guarantees the pump and the heartbeat never overlap and overwrite each other.

Inspect history

  • GET /api/state — JSON snapshot (metrics, active, candidates, timeline, logs).
  • GET /gen/:id — full JSON for one generation (source, statuses, diffs).
  • Or run sqlite queries against this val's project-scoped database (std/sqlite/main.ts): the generations, evolution_log, and meta tables.

Environment variables

  • OPENAI_MODEL (optional) — pick a specific model. If unset, std/openai uses its default. Do not set a hard-coded unverified model.

Safety model

Generated source is DATA ONLY and is never executed. Validation is layered (markers, claimed values, balanced delimiters, meaningful diff, forbidden capabilities, control-subversion detection). The sandbox is a structural static gate. The fixed control system (validation / approval / rollback) is never reachable from generated source.

API

GET  /             → dashboard
POST /advance      → run one evolution cycle (the pump's heartbeat)
POST /approve/:id  → approve a PENDING generation
POST /reject/:id   → reject a generation
POST /rollback/:id → restore a generation as ACTIVE
GET  /api/state    → JSON snapshot
GET  /gen/:id      → one generation