Skip to Content
Energon runs in the operator's Cloudflare account. Published links are open by default.
Operate an InstanceUpgrade and recover

Follow this procedure to merge upstream changes, deploy a schema update, or recover interrupted retention cleanup without putting production data at risk. It is written for the human operator who controls the D1 database and Worker deployment. The order matters because runtime bootstrap and stale-claim recovery cover only specific failure cases: validate, migrate D1, deploy the Worker, and verify the live contract. For loss of catalog or object data, use Back up and restore D1 and R2 instead.

Upgrade and recover an instance

Migrate before the Worker changes

Energon represents schema in three places: append-only migrations record deployment history, src/db.ts creates and upgrades runtime tables, and src/schema.sql documents the current shape. Runtime bootstrap helps old instances start, but SQLite CREATE and ADD COLUMN migrations are not generally idempotent. Deploying code first can therefore create a column before Wrangler records its migration.

1. Validate the fork locally

After merging upstream, take new configuration keys from wrangler.example.toml, keep instance customizations in supported variables and instance-skill.json, and run the repository gates:

npm install npx wrangler d1 migrations apply energon --local npm run skill:render -- --check npx wrangler types npm run typecheck npm run lint npm test

The schema tests require runtime table declarations and src/schema.sql to expose the same columns. The database unit test also verifies that a 0005-shaped instance gains needed columns before indexes are created.

2. Migrate before deploying

For production, prefer the checked-in GitHub Actions job. It runs tests, applies remote migrations, and deploys only after migration succeeds. ENABLE_PRODUCTION_DEPLOY=true activates that job for pushes to main; leaving it unset keeps CI test-only.

If a human operator intentionally uses Wrangler from an authenticated local laptop, the order is still:

npx wrangler d1 migrations apply energon --remote npx wrangler deploy

Do not reverse these commands. Do not run them from an untrusted cloud agent environment.

3. Recover from a duplicate-column migration failure

A duplicate-column error after a Worker-first deployment indicates that runtime bootstrap may already have added the column while Wrangler still considers its migration pending.

  1. Stop the deployment; do not retry the same migration loop blindly.
  2. Have a human operator inspect the affected table with PRAGMA table_info in the Cloudflare D1 console.
  3. Compare the actual column and type with the pending migration and the current runtime schema.
  4. Only after confirmation, follow the human production procedure to record that migration as applied.
  5. Rerun the normal migrate-before-deploy workflow and all verification checks.

Agents must not hand-edit d1_migrations, run production d1 execute, or improvise repair SQL. If no human can verify the actual production schema, leave the deployment stopped and escalate with the migration filename and the observed error.

Migration 0005_handles.sql needs special care: it rebuilds the site tables to use (handle, slug) as the primary key. Runtime ensureSchema can add a handle column but cannot reshape an old primary key. Follow the migration’s warning rather than applying the rebuild to an already runtime-modified database.

4. Respect the token-expiry rollback floor

Once any token has a non-null expires_at, an older Worker that predates expiry enforcement would authenticate finite-lifetime tokens again, including expired ones. Before considering a rollback below that build, a human operator must identify all active finite-lifetime tokens:

SELECT id, user_email, label, expires_at FROM tokens WHERE expires_at IS NOT NULL AND revoked_at IS NULL;

Stay on or above the first expiry-enforcing build whenever possible. If a deeper rollback is unavoidable, the owners must revoke those tokens before the old Worker becomes active. To audit Never tokens after disabling future Never mints, use the same query with expires_at IS NULL.

ALLOW_UNLIMITED_TOKENS=false is not a recovery control for existing credentials. It removes Never only from future mint choices. Revoke existing tokens explicitly before a rollback or policy tightening that requires them gone.

5. Understand expiry-cleanup recovery

Expiry has two enforcement paths. Cron selects at most 100 expired sites and 100 expired loose files per run. Reads and writes independently return 410 for expired objects and schedule a targeted purge, so a missed cron does not revive content.

Purge claims are written before R2 deletion so a concurrent TTL patch or file replacement cannot preserve a catalog row whose bytes are disappearing. A failed R2 delete restores the prior writer. A fresh claim blocks a second purger; a claim at least 60 seconds old may be reclaimed automatically.

claim exact expired row | v delete R2 bytes -- failure --> restore prior writer, surface error | v delete child rows --> delete owner row --> purge cache prefix --> release quota

If cleanup appears stuck, first confirm whether the object still returns 410 and whether the next cron run reclaims the stale claim. Do not delete .wrangler/state during local investigation; it contains the human’s local database. Do not kill unrelated Wrangler or workerd processes by pattern.

6. Verify after upgrade or recovery

curl -fsS https://energon.company.example/v1/health curl -fsS https://energon.company.example/v1/help npm run skill:render -- --check

Confirm health, resolved retention and token policy, instance identity, capacity limits, and rendered-plugin consistency. For a schema incident, preserve the failing migration filename, the exact error, the human’s schema evidence, and the successful rerun result.

Stop conditions

Never rewrite an old migration to match the current schema. Add new history under migrations/, keep runtime bootstrap aligned, and update src/schema.sql as the current documented shape.

Never deploy the Worker before migrations. If it already happened, stop and use the human-only verification procedure above; do not let an agent stamp migration state.

Never roll back below token-expiry enforcement while active finite-lifetime tokens remain. Stay above the floor or revoke them first.

Keep upgrades reviewable

The cleanest upgrades keep instance changes in wrangler.toml variables and instance-skill.json, then rerender the plugin after an upstream merge. That reduces conflicts in hub source and makes drift machine-checkable. Review Configure instance policy before accepting new defaults, Back up and restore D1 and R2 for data-loss incidents, Deploy an Energon host for the guarded workflow, and Operate an instance for the full lifecycle model.

Last updated on