By Vicente Arteaga Gomez
MisLinux
This is part of my Kubernetes-on-Hetzner-and-operations series on MisLinux. It describes how I actually use AI coding agents for business and operations work — not as a chatbot, but as a compiler from messy intent into durable automation.
Most "AI for business" content stops at drafting emails or summarizing meetings. That is fine. It is also ephemeral.
The pattern that changed my operations work is different:
> Every time I catch myself doing a manual chore twice, I ask the AI to implement a scripted, tested procedure — and I capture the nuance in AGENTS.md or SKILL.md.
Manual intervention becomes the exception. Randomness shrinks.
The loop I use
1. Do the task once with AI assistance (read-only first)
2. Demand a script/program that encodes the steps
3. Add tests at the strongest safe level (unit → smoke → integration)
4. Record Context / Intent / Rationale in AGENTS.md
5. Save proof artifacts from the first real run
6. Next time: rerun the script, not the conversation
Step 2 is the discipline. Without it, AI becomes a very fast way to recreate tribal knowledge in chat logs.
Example: from spreadsheet panic to finance fill automation
Finance month-close used to fail loudly but opaquely: a missing title row, a renamed column, a wrong rev-share cell — and the operator rebuilt context from memory under time pressure.
The automated path now:
| Layer | Purpose |
|---|---|
| PHP fill libraries | Deterministic column mapping + rev-share math |
| CronJob in cluster | Scheduled run with read-only staging inputs |
| PHPUnit | Locks mapping rules offline |
| CIR in AGENTS.md | Explains why Spanish locale uses comma decimals |
| Failure email | Includes sheet URL, stage, excerpt, relaunch command |
The AI did not "run finance." It helped me extract the invariant rules and encode them where regressions are caught before production.
Example: publisher onboarding as manifest-driven automation
Another class of business work: onboarding a publisher across ad server, dashboards, tags, and internal CMS records.
The AI helped build:
onboard.php --plan / --applyover YAML manifests- Readiness checks wired to Telegram on failure only
- Funnel diagnostics (wrapper traffic → ad server → dashboard revenue)
Each piece has tests. Each non-automatable seam is labeled EXTERNAL in plan output instead of silently skipped.
That is business automation: the contract is in git, not in someone's notebook.
Where AGENTS.md and SKILL.md fit
Models forget. Repositories should not.
| File | What it captures |
|---|---|
AGENTS.md | Context / Intent / Rationale ledger — why the system looks this way |
SKILL.md | Operator runbook — ordered steps, inputs, safety gates |
| Top-of-file CIR in scripts | Why this script exists and what breaks if reverted |
When a future agent (or human) asks "why is this weird?", the answer is searchable.
Good CIR entry shape:
- Context: what was happening.
Intent: what we wanted.
Rationale: why this approach; what we discarded; what re-breaks if reverted.
Without Rationale, the next person "cleans up" the guardrail that prevented yesterday's outage.
Tests are the guardrails, not decoration
I default to PHPUnit in this repo. Python appears where browser CDP is genuinely better — not because a one-off was faster in Python.
Test layers I aim for on operational code:
| Layer | Catches |
|---|---|
| Unit | Pure logic regressions (parsers, planners, diff engines) |
| Smoke | CLI wiring, --help, required args |
| Fuzzy / property | Random inputs that must not crash or violate invariants |
| Integration | Fixture pipelines end-to-end offline |
| Gated e2e | Live API/browser only when explicitly enabled |
If a layer is impractical, the blocker goes in AGENTS.md with the nearest safe substitute. "No tests" is not silent.
How I prompt AI so the output is durable
Weak prompt:
> Fix the control panel numbers for one publisher row.
Strong prompt:
> Read the existing control-panel updater. Add a read-only second pass that filters ad requests using intranet flags. Must be idempotent, PHPUnit-tested, CIR in AGENTS.md, dry-run default, and include exact kubectl job command for one-off proof.
The second prompt forces artifacts — the things that survive the session.
Reducing manual points reduces randomness
Every manual step is a slot for:
- Wrong network selected
- Stale OAuth token
- Spreadsheet column drift
- "I thought we already ran that"
Automation does not mean zero humans. It means humans approve gates, not re-type data.
My practical metric: count manual decisions per run. If a process still needs ten, the next AI session should remove two — with tests.
What AI is bad at in business automation
Be explicit about limits:
- Economically loaded ad server UI changes without human confirm
- Irreversible production mutations without dry-run proof
- Legal/commercial judgment on contract terms
- Pretending read-only credentials can write because "the script should"
The manifest/onboard pattern works because it separates check from apply and labels EXTERNAL work honestly.
Checklist: is this real automation?
Before I merge operational tooling, I ask:
- [ ] Can a new operator rerun it from
--helpoutput alone? - [ ] Does dry-run exist and default to safe?
- [ ] Is there at least one automated test locking the core logic?
- [ ] Is there a CIR entry explaining discarded alternatives?
- [ ] Does failure output say what was expected vs what was found?
- [ ] Is there a saved artifact from a successful run?
If most boxes are empty, I have a chat transcript — not automation.
Tie-in to AI-assisted development hygiene
Two sibling posts on this blog:
- How I Use CIR Notes to Make AI Coding Agents More Useful
- How I Fixed Cursor Getting Slower Every Message — keep indexer noise out of the repo so agents stay fast
Business automation and dev environment hygiene are the same strategy: make the machine repeat the boring truth, and document why the truth looks odd.
---
Independence note: Tools mentioned (Copilot, Claude, Codex, Cursor, Google Ad Manager, Kubernetes) reflect my stack. No vendor sponsorship implied.