Your AI Ops Bot Is Not Your Co-Founder: Guardrails First
Letting an agent touch production needs blast-radius limits, not trust. The guardrails to set first, the failure modes they stop, and where to keep a human.
Filed under Agent Reliability· see every report on this topic
Verdict. If you run a cron against billing, trading, or production, do not give it operator keys and tell it to “use judgment.” Give it a narrow read-only lane, require logged human approval for every mutation, and keep escalation paused by default. In July, two automated config pushes changed a real-money Polymarket bot; the second caused financial loss, but the exact amount was not recorded.
The operator and the leak: your monitor can deploy
A scheduled agent can read a dashboard, spot a bad number, and look harmless. The boundary changes when “fix it” can alter revenue, price, access, or execution. That is the AI ops bot production-guardrails decision: not whether an agent can read a graph, but whether the same unattended process can write configuration, reload a service, select a branch, or correct state it does not understand.
The July 5 receipt for PID 110351 shows the monitor’s useful work. At 01:01 IST it reported 13 wins / 11 losses, +$5.42 PnL, 54.2% win rate, and 1.47 profit factor. At 05:03, it was 22 wins / 29 losses and -$7.88. DOGE had 10 trades and -$7.87, so the monitor cut DOGE from $2 to $1. (Receipt: ~/.hermes/kit-log.md, 2026-07-05 01:01 and 05:03 entries, preserved in cron sessions 76938 and 79083.)
The leak was not observation. The monitor could push local config.yaml and reload live operation. It was an unattended production operator, not a reporter proposing a change. As our guide to workflow automation choices puts it in a different context, an automation is cheap only while its failure is cheap. A bot touching money has a different failure budget.
Split seeing from changing
Keep these lanes separate:
- Observe: collect bounded read-only health, recent events, limited aggregates, and the approved configuration fingerprint.
- Explain: report the evidence and propose a diff. The monitor may recommend pause, rollback, or a field change, but cannot execute it.
- Approve and apply: a named human reviews and logs the diff. A separately scoped writer applies only that approved diff, then records the version or reload receipt.
This is not process for process’s sake. A cron cannot know whether another agent has a branch checked out, whether an emergency server setting is deliberate, or whether a temporary divergence is correct.
The local scripts/monitor.py proves that a read-only lane can still report enough to make decisions. It uses Paramiko, captures the dashboard as the bot user, and uses SQLite reads against the journal. It calculates session totals, per-asset trades, wins, win rate, PnL, cost, streaks, hourly results, and recent fills. Its config parser reports per-asset bet and stop-loss maps on a $1–$5 grid. (Receipt: /Users/kit/projects/polymarket/scripts/monitor.py, lines 1–25, 104–157, 160–208, and 241–255.)
The policy also bars deploys, restarts, stops, and reconfiguration without explicit approval; it bars full production-database scans or copies. Its historical journal-bloat note puts disagreement_polls at roughly 93 million rows / 50GB. Research uses static backups and O(trades) extraction instead. (Receipt: /Users/kit/projects/polymarket/AGENTS.md, lines 21–29; GBrain projects/polymarket-bot.) The monitor may answer “What changed?” It may not decide “I will change it back.”
The two production-write receipts
Incident A: hourly sync reverted deliberate work
On July 5, hourly cron c2269ff8f672 pushed local config.yaml to the live server. The local file had old v_min values; an operator had deliberately lowered the server values for trade frequency. The cron restored the older, tighter gates, and the bot missed trades. The incident traces the route to the polymarket-ops skill, which instructed ./deploy.sh reload for issues. (Receipt: kit-log, 2026-07-05 “Cron config-overwrite incident”; session 20260704_210838_f20d6a, messages 85235–85237.)
The remediation was read-only: rewrite the cron prompt, reduce its cadence from 1 hour to 6 hours, and add a cron guard to the skill. This was a capability-boundary failure, not a bad model answer: a local working copy had an unreviewed write path to a real-money system.
Incident B: a development branch reached production
On July 6/7, a background Kanban/delegated agent worked in ~/projects/polymarket/ on disagreement-strategy-v14.3. It committed fr-edge config changes: cut-overlay, $2 base sizes across assets, -$5 stop-loss, and re-enabled SOL. The hourly cron ran cd ~/projects/polymarket && ./deploy.sh reload, deploying that development-branch config instead of the intended fable-branch configuration. (Receipt: kit-log, 2026-07-06/07; session 20260704_210838_f20d6a, message 85488.)
The corrupted fields were observe_only, v_min, order_price_buffer, edge_enabled, bet sizes, and stop-loss. The result was financial loss from trading with the wrong configuration. No receipt records the amount. That means there is no honest incident total to calculate; the missing amount also shows why actor, diff, approval, timestamp, deploy receipt, and business outcome need an append-only record.
The response:
- Move the cron to
/Users/kit/projects/polymarket-lat-ops/so it cannot touch the old directory. - Restrict the prompt to
/tmp, fixed bet sizes, and no Git operations. - Add KANBAN/DELEGATION BLOCKED to the operations skill.
- Mark the old project path stale and block cron and delegated work there.
- Pause the cron until manual resumption.
Path warnings are not enough. Use separate credentials: the observer has no production mutation token, and the writer accepts a signed or logged change request, not a conversational instruction.
Compare authority before automating
This is a comparison of authority, not vendors. A different model cannot repair unsafe permissions.
| Approach | Good for | Cost shape | Catch |
|---|---|---|---|
| Broad autonomous operator | Throwaway sandboxes | Cheap until it writes | Wrong context can mutate production |
| Read-only AI monitor | Money and production systems | Build reporting first | Cannot self-remediate |
| Approval-gated writer | Small reviewable changes | Human review time | Needs durable diff and log |
| Deterministic runbook | Known reversible incidents | Engineering time | Fails outside assumptions |
| Do nothing / fix process first | No receipt or owner | $0 | Keep humans on console |
Start with the read-only monitor. Add an approval-gated writer only when you can name every writable field, its rollback, its approving human, and its landing receipt.
The human boundary did not prevent action on July 5. At 13:02, positive recent 20-trade / one-hour windows restored DOGE from $1 to $2. deploy.sh reload hit a branch-mismatch prompt, so the change used manual SCP plus SIGUSR2 fallback and verified config_reloaded. (Receipt: kit-log 2026-07-05 13:02; cron session 79518.) The tool identified an unsafe branch context; a person made the intervention explicit.
Price authority honestly
The receipts do not support a dollar total for either incident. What they show is an unattended hourly config push, a wrong branch, altered risk fields, and real-money execution.
| Timestamp / PID | Result | Per-asset detail | Receipt |
|---|---|---|---|
| July 5, 01:01 | +$5.42; 13/11; 54.2%; 1.47 PF | — | Session 76938 |
| July 5, 05:03 | -$7.88; 22/29 | DOGE: 10 trades, -$7.87 | Session 79083 |
| July 5, 19:02 | -$11.84; 46/60; 43.4%; 0.80 PF | — | Session 81668 |
| July 6, PID 130583 | 136 trades; +$4.20; 47.1% | BTC +$7.57; DOGE +$6.57; XRP +$0.35; ETH -$5.07; BNB -$5.22 | Sessions 89555, 83094 |
These are session snapshots, not proof that one config action caused each change. July 6 also changed ETH’s stop-loss from -10 to -8 through the manual fallback after a branch-mismatch prompt. Treating ordinary performance variance as deploy impact would be another unsupported claim.
The cost is not an agent subscription. It is the worst change an unattended process can apply before anyone sees its report. If that cost matters, remove the unattended writer.
Failure modes to name before granting keys
The stale-local overwrite. A local file is not necessarily the source of truth. If an operator made a deliberate production adjustment, a “sync” can erase it with no syntax error and no obvious outage. Incident A is this failure mode exactly.
The working-directory branch leak. cd is an authorization decision when the directory can contain a different branch and a different config. Incident B turned a development workspace into a production deployment source.
The skill becomes a permission escalator. A prompt or skill that says “reload on issues” is not harmless guidance when a cron has deploy access. It turns broad language into a repeatable mutation route.
The monitor confuses reporting with repair. A health check can safely say an asset is losing. It cannot safely infer that it should rewrite stop-loss, re-enable an asset, or change risk gates without knowing the current experiment and approved intent.
The unbounded evidence query. A monitor that scans every historical row can become its own outage. The policy’s ~93M-row / 50GB journal history is the receipt: limit queries by process or time, use static backups for research, and keep operational reads proportional to trades. (Receipt: /Users/kit/projects/polymarket/AGENTS.md, line 25; GBrain projects/polymarket-bot.)
The silent money story. “Financial loss” was recorded, but not the amount. Without an append-only change log that ties actor, diff, approval, timestamp, deploy receipt, and business outcome together, you cannot distinguish strategy variance from configuration damage after the fact.
When not to use an AI ops bot: fix the process for $0
Do not add the monitor when any of these is true:
- You cannot name a single human owner for each production config.
- You have no approved-config snapshot, or no rollback command tested outside an incident.
- The agent needs broad SSH, cloud, database, or deployment credentials just to produce a report.
- Another worker can edit the same working tree or configuration at the same time.
- Your metrics are not bounded and attributable; “the dashboard looked bad” is not a change request.
- You cannot show the last change, its approver, and the evidence that it actually landed.
Freeze unattended mutations, write a plain change log, create a read-only collector, and have a person run the existing deploy procedure. That is not anti-automation; it is not automating ambiguity. A model swap also does not solve it: the local inference field guide reaches the parallel conclusion that a reference lane and contract validation come before a production cutover.
Bottom line
An AI production watcher is an observability component with a convincing interface. Build narrow reads, bounded evidence, a visible proposal, explicit human approval, and a writer separate from the watcher.
The July receipts support monitoring and reject unattended authority. Build reporting first, keep mutation paused by default, and let the approval log, not model confidence, decide whether production changes.
More on this decision, three ways to look at it:
Sources
~/.hermes/kit-log.mdhistorical entries for 2026-07-05 and 2026-07-06/07, preserved in Hermes session transcripts: incident A (20260704_210838_f20d6a, messages85235–85237), incident B (85488–85490), and monitor snapshots (76938,79083,79518,81668,83094)./Users/kit/projects/polymarket/scripts/monitor.py, read-only collection design, bounded session/per-asset calculations, config parsing./Users/kit/projects/polymarket/AGENTS.md, current safety policy and journal-query boundary.- GBrain:
sessions/digest/2026-07-07andprojects/polymarket-bot, incident cross-check and historical operating context.
Get the next verdict before it's everywhere.
One email when a new lab post or cost table ships. No spam, no confirmation step — unsubscribe anytime.