---
title: "Run one-off tasks as reviewed scripts · Agent Wranglers"
url: https://agentwranglers.se/playbook/engineering/running-in-production/admin-tasks-as-code
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Run one-off tasks as reviewed scripts

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Running in production](https://agentwranglers.se/playbook/engineering/running-in-production.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

- ID: ENG-43
- Level: Recommended
- Chapter: [Running in production](https://agentwranglers.se/playbook/engineering/running-in-production)
- Rule: Write every data fix and admin task as a script in the repository. Run it from the deployed release, dry run first, and log who ran it.
- How: A query typed by hand on the production database has no review, no test and no record. A fix to data itself follows [fix production data with a reviewed script](https://agentwranglers.se/playbook/data/migrations/data-fixes). This rule covers every other one-off task. Commit the script and review it like any change. Ship it with the release, so it runs with the same code, dependencies and settings as the app. Make it print what it would change by default, and write only with a flag such as `--apply`. Run the write in one [transaction](https://agentwranglers.se/playbook/data/transactions-and-concurrency/transactions), and stop when the count differs from the dry run. Log the script, the person and the count. Take a backup first, as [encrypted backups](https://agentwranglers.se/playbook/data/backups-and-recovery/encrypted-backups) describes. Schema changes go through [migrations](https://agentwranglers.se/playbook/data/migrations/versioned-migrations) instead.
- Check: Every script in the admin folder changes 0 rows when run without `--apply` against a test copy. The database audit log for the last 30 days shows no write from a person's own account, only from the task runner's account.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
// scripts/fix-order-totals.js, run with: node scripts/fix-order-totals.js [--apply]
const isApply = process.argv.includes('--apply');
const rows = db.prepare('SELECT id FROM orders WHERE total_cents < 0').all();
console.log(`${rows.length} orders to fix`);
if (isApply) {
  db.transaction(() => {
    const { changes } = db.prepare('UPDATE orders SET total_cents = 0 WHERE total_cents < 0').run();
    if (changes !== rows.length) throw new Error(`Expected ${rows.length}, changed ${changes}`);
  })();
  log.info({ task: 'fix-order-totals', user: process.env.USER, changed: rows.length });
}
```

### Python example

```python
# scripts/fix_order_totals.py, run with: python -m scripts.fix_order_totals [--apply]
import os, sys
is_apply = "--apply" in sys.argv
ids = [row[0] for row in db.execute("SELECT id FROM orders WHERE total_cents < 0")]
print(f"{len(ids)} orders to fix")
if is_apply:
    with db:
        changed = db.execute("UPDATE orders SET total_cents = 0 WHERE total_cents < 0").rowcount
        if changed != len(ids):
            raise RuntimeError(f"Expected {len(ids)}, changed {changed}")
    log.info("fix-order-totals", extra={"user": os.environ["USER"], "changed": changed})
```

## Sources

- [The Twelve-Factor App: Admin processes](https://12factor.net/admin-processes)

## Related rules

- [Fix production data with reviewed scripts](https://agentwranglers.se/playbook/data/migrations/data-fixes) in Data
- [Wrap multi-step changes in a transaction](https://agentwranglers.se/playbook/data/transactions-and-concurrency/transactions) in Data
- [Encrypt backups](https://agentwranglers.se/playbook/data/backups-and-recovery/encrypted-backups) in Data
- [Change the schema only with migrations](https://agentwranglers.se/playbook/data/migrations/versioned-migrations) in Data
- [Keep manual operations work under half the time](https://agentwranglers.se/playbook/operations/running-the-service/limit-toil) in Operations

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/engineering/running-in-production/admin-tasks-as-code">Agent Wranglers engineering playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Keep secrets in a secrets store](https://agentwranglers.se/playbook/engineering/running-in-production/secrets-store)
- [Running in production](https://agentwranglers.se/playbook/engineering/running-in-production)
