Operational work is where a terminal agent is most useful and where the consequences of a wrong command are worst.
The context is already in the terminal — the failing build, the log tail, the kubectl describe full
of events — which is exactly the material an agent reads well. And the remedial commands touch systems
that people depend on.
This lesson is the safeguards. The following lessons apply them to specific technologies.
Credentials: what not to give it
Section titled “Credentials: what not to give it”The most important section, and the shortest.
Do not run an agent in a shell with production credentials loaded.
The CLI inherits your environment: environment variables, cloud CLI sessions, kubectl context,
credential helpers. Its effective permissions are your permissions, and nothing about the approval
prompt changes what a command can reach once approved.
The practical arrangement:
Separate shells. One for agent work with read-only or development credentials; one for production operations, without an agent.
Read-only by default. Most diagnostic work — reading logs, describing resources, explaining a
plan — needs no write access at all. An AWS profile with read-only policies, a Kubernetes context bound
to a view role.
Short-lived credentials. Assumed roles with a session duration, not static keys. The same standard Pillar 5 applies to every other machine identity.
Know your context before you start.
kubectl config current-contextWhat it doesPrints the Kubernetes context the next kubectl command will use.
Why we run itAn agent running kubectl uses whatever context is active. Establishing which cluster that is before starting is the difference between a diagnostic session and an incident.
Expected resultThe current context name.
The cloud equivalents — aws sts get-caller-identity, gcloud config list, az account show — are
worth running for the same reason and take a second each.
The read-only-first pattern
Section titled “The read-only-first pattern”The habit that makes operational agent work safe, stated as an instruction you give at the start of a session:
Diagnose this using read-only commands only. Do not propose anything that changes state until I have seen the output and asked for it.
That converts the interaction from “here is a fix” to “here is what is happening”, which is the correct order and produces better remedies anyway — a fix proposed after reading the actual state is better than one proposed from a description.
The read-only commands by domain:
| Domain | Safe to run freely |
|---|---|
| Shell | ls, cat, grep, find, ps, df, du, tail |
| Git | status, log, diff, show, blame, reflog |
| Docker | ps, images, logs, inspect, history |
| Kubernetes | get, describe, logs, events, top, explain |
| Terraform | validate, fmt -check, show, state list, plan |
| AWS | describe-*, list-*, get-* |
| GitHub | gh run view, gh pr view, gh api on GET endpoints |
Pre-approving these classes and nothing else is the configuration most operational sessions want.
Dry runs and previews
Section titled “Dry runs and previews”Where a destructive operation has a preview, use it and read it.
{/* Kubernetes: what would change, without changing it */}kubectl diff -f manifest.yamlkubectl apply -f manifest.yaml --dry-run=server{/* Terraform: the plan is the review artefact */}terraform plan -out=tfplanterraform show tfplan{/* Git: what would be removed */}git clean -ndThe pattern to insist on: the agent produces the preview, you read it, then you decide. A session where the agent runs the preview and then immediately proposes the apply has compressed two decisions into one, and the second is yours.
Worth stating as a repository instruction where this surface is used regularly:
- For any operation with a dry-run or plan mode, run that first and show me the output before proposing the real command.- For any destructive command, state what it does and what would be lost.Logs and diagnosis
Section titled “Logs and diagnosis”The highest-value, lowest-risk application, and the one that justifies the whole surface.
Reading a failure. A stack trace, a container log, a build output. The agent reads the actual text rather than your summary of it, which is the same discipline as AI Git troubleshooting and matters more here because operational output is longer and denser.
Correlating. “Here are the application logs and the Kubernetes events for the same window. What happened?” Cross-referencing two sources is genuine work that an agent does quickly.
Narrowing. A hundred megabytes of log is not something to paste. The agent can grep, tail and
filter — which is the loop that makes large logs tractable.
The caution specific to logs: they contain data. Customer identifiers, request bodies, tokens in headers. An agent reading a production log is a log being sent to a model provider. Where that matters, redact before reading or work from a sanitised copy — and note that this is the same concern as pasting a diff, at a larger scale.
GitHub Actions
Section titled “GitHub Actions”Operational work on pipelines, where the agent’s ability to read run output helps.
{/* Read a failed run's logs */}gh run view --log-failedThis workflow run failed. Read the failed step’s logs and tell me why. Do not change the workflow yet.
That is a good use: the failure output is long, the relevant part is buried, and finding it is mechanical.
Two boundaries.
Workflow files are privilege changes. A change to .github/workflows/ changes what runs with your
repository’s credentials. Treat an agent-proposed workflow edit as the privilege change it is, and
route it through review — a CODEOWNERS entry on /.github/ makes
that automatic. See workflow security.
gh can write. gh includes merging pull requests, closing issues, and changing settings. Allow
shell(gh) separately from shell(git), and prefer the
GitHub MCP server in read-only mode for anything diagnostic.
Shell work
Section titled “Shell work”The base case, and where most operational agent use starts.
Explaining a pipeline. A shell one-liner somebody wrote three years ago, with four pipes and an
awk expression. Asking what it does is a reading-comprehension question with a checkable answer, and
it is genuinely faster than working it out.
Building one. “Find every file over 100MB modified in the last week, excluding .git.” The agent
produces a command; you read it before running it. The reading is the point — a find with -delete
on the end looks very similar to one without.
Debugging quoting. Shell quoting is a common source of subtle bugs, and an agent that can run the command and read the error iterates faster than a human guessing.
The specific risks with generated shell:
Glob expansion. rm -rf $DIR/* with an empty DIR is a different command from the one intended.
Ask what happens when a variable is empty.
Word splitting. An unquoted variable containing a space behaves differently from one that does not, and the failure is data-dependent.
Silent failure. A pipeline where an early command fails but the exit status comes from the last one.
set -euo pipefail exists for this, and an agent will not add it unless asked.
Destructive flags in the middle. -delete, -exec rm, --force. Read to the end of the command
before approving it, not just the beginning.
Copilot CLI for Bash covers this properly.
Containers
Section titled “Containers”Diagnostic container work is safe, frequent, and a good fit.
{/* Why did this container exit? */}docker logs --tail 200 CONTAINERdocker inspect CONTAINERThis container is restarting. Here is
docker ps -aand the last 200 log lines. What is happening?
Where it helps most: build failures, where the output is long and the actual error is buried; and
image size, where an agent reading a Dockerfile and docker history can identify which layer is
large and why.
Where to be careful: anything that removes. docker system prune is convenient and deletes more than
people expect — images, containers, networks, and with -a or --volumes a great deal more. That is a
command to type yourself.
Infrastructure as code
Section titled “Infrastructure as code”The domain where the read/write boundary is clearest, because the tooling has a built-in preview.
Terraform’s plan is the review artefact. An agent reading a plan and explaining what it does — how many resources, which are replaced rather than updated, what the replacements would destroy — is doing useful work on output that is genuinely hard to read.
The critical distinction, which the Terraform lesson covers in full: a plan that says “1 to destroy” is a plan that will destroy something. Reading the plan is the control, and the agent’s summary of it is an aid to reading rather than a substitute.
Never let an apply be a step in an agent session. Infrastructure changes belong in a reviewed
pipeline with state locking, approvals and an audit trail — see
Deploy Terraform. An interactive terraform apply bypasses all of it.
The same holds for Kubernetes: kubectl diff and --dry-run=server are the previews, and applying to
a live cluster from an agent session is the operation to keep out of the loop.
Incident investigation
Section titled “Incident investigation”The scenario where an agent helps most and where the discipline matters most, because everything is urgent.
-
Establish context first. Which cluster, which account, which environment. Thirty seconds, and it prevents the worst class of mistake.
-
Read-only only, explicitly stated. During an incident is precisely when a state-changing command gets approved without reading.
-
Gather in parallel. Logs, events, recent deploys, recent merges. The agent can run several queries and correlate.
-
Ask for hypotheses with evidence. “What could explain this? For each, name the log line or event that supports it.”
-
Verify a hypothesis before acting on it. The read-only commands that would confirm or refute.
-
Decide the remedy yourself. Then run it yourself, or approve it having read it.
-
Capture what you learned while it is fresh — the timeline, the commands, the conclusion.
Step 6 is not ceremony. Under incident pressure, the temptation to approve a plausible remedy is at its strongest, and the cost of a wrong one is at its highest. That combination is the argument for the rule rather than against it.
An operations agent
Section titled “An operations agent”The durable configuration for this work: an agent whose framing is diagnosis and whose tools reflect that.
---name: ops-doctordescription: Diagnoses operational problems from logs, events and configuration. Read-only — never changes infrastructure state.tools: ["read", "search", "shell"]---
You diagnose operational problems. You explain what is happening and what theoptions are. You do not change anything.
Rules:
- Only run read-only commands. For kubectl: get, describe, logs, events, top, explain. For docker: ps, logs, inspect, history. For terraform: validate, show, state list, plan. For cloud CLIs: describe-*, list-*, get-*.- Never run: apply, delete, create, patch, scale, rollout, prune, destroy, or anything with --force.- Before any diagnosis, confirm and state which cluster, account or environment the commands are running against.- Report the commands you ran and the output you based conclusions on.- When proposing a remedy, describe what it does, what it would change, and what the dry-run equivalent is. Do not run it.Three things that agent does which a general session does not.
It states the environment. The most valuable line, because “which cluster am I in” is the question whose wrong answer causes the worst outcomes.
It cites its evidence. Conclusions with the commands and output behind them are checkable; an unsupported diagnosis under incident pressure is a guess you might act on.
It offers the dry-run. Making the safe version the default proposal is a small framing change with a large effect on what gets approved.
The honest caveat, as in the Git lesson: the instructions are a request. The
tool list is the control, and a
preToolUse hook matching dangerous command patterns is the
enforcement. For a team doing this regularly, the hook is worth building.
What not to let it do
Section titled “What not to let it do”Anything against production without you reading the command. No exceptions worth writing down.
--allow-all-tools in a shell with any real credentials. This is the configuration where a
misunderstanding becomes an outage.
Applying infrastructure changes. terraform apply, kubectl apply against a live cluster, a
deployment command. These belong in a
reviewed pipeline, not an interactive session.
Modifying credentials or access. IAM changes, key rotation, permission grants.
Deleting anything. Resources, volumes, namespaces, buckets. The preview is --dry-run; the decision
is yours.
Working across environments in one session. A session with both staging and production context available is a session where the wrong one gets used.
Blast radius, as a habit of mind
Section titled “Blast radius, as a habit of mind”The question worth asking before approving any operational command, in the form that makes it quick.
What is the scope of the target? A command with a specific resource name is bounded. One with a
label selector, a glob or --all is not, and the difference is one flag.
{/* Bounded */}kubectl delete pod api-server-7d4f8b6c9-x2k4m
{/* Not bounded */}kubectl delete pods --allWhat is the scope of the context? The same command against staging and production differ only in a context nobody can see in the command text. This is why establishing context first is not ceremony.
Is it reversible? A deleted pod comes back if a controller manages it. A deleted persistent volume claim does not. A dropped table does not. The distinction is not visible in the command’s shape.
Who else is affected? A restart during business hours, a scale-down that removes capacity, a migration that locks a table. The command may be correct and still be the wrong thing to do right now.
What would I do if this were wrong? If the answer is “restore from backup”, confirm the backup exists before rather than after. If the answer is “I do not know”, that is the finding.
Five questions, fifteen seconds, and they are the same five whether the command came from an agent or from your own memory. The reason to write them down here is that an agent makes commands arrive faster than they used to, and a habit that was implicit when you typed everything needs to become explicit when you are approving.
Auditability
Section titled “Auditability”An interactive agent session leaves no durable record, which is a real gap for operational work.
What survives: whatever is in your terminal scrollback, and the effects of the commands that ran.
What does not: why you did it, what you considered, what the agent reported, and what you decided not to do.
For anything that touched a shared system, that matters. Three cheap mitigations:
Save the session. /session names sessions and /share generates a share code; a named session is
findable later. Better than scrollback, and still local.
Write the timeline as you go. During an incident, a running note of “at 14:22 I ran X, output showed Y, concluded Z” is worth more afterwards than any tooling. The agent can draft it from the session at the end.
Put conclusions where the team looks. An incident channel, a ticket, a post-incident document. A conclusion in a terminal session is a conclusion one person has.
The related point for regulated environments: an interactive agent session is not an audit trail. Where change control requires one, the change belongs in a pipeline that produces records — which is another reason applies belong there rather than in a session.
Hooks can help. A sessionStart and sessionEnd hook that logs to a central location, or a
preToolUse hook that records every command, turns an ephemeral session into something with a record.
See Building repository AI agents.
Common mistakes
Section titled “Common mistakes”Running in a shell with production credentials. The agent inherits them.
Not checking the context first. Which cluster, which account. Seconds, and it prevents the worst outcome.
Approving an apply because the plan looked fine. The plan is evidence for a decision, not the decision.
--allow-all-tools because approvals are slow. Slow is the point during operational work.
Pasting production logs without thinking about their contents. Customer data, tokens, identifiers.
Letting it edit workflow files casually. That is a change to what runs with your credentials.
Using it to move faster during an incident. Use it to understand faster. The acting stays deliberate.
One session spanning environments. Separate sessions, separate credentials.
Where operational AI genuinely helps
Section titled “Where operational AI genuinely helps”Being specific, because the safeguards on this page could read as “do not use it”.
Reading things nobody wants to read. A thousand-line build log, a describe output with forty
events, a Terraform plan with two hundred resource changes. This is where the time actually goes in
operational work, and it is mechanical.
Correlating sources. Application logs alongside cluster events alongside recent deploys. Doing this by hand means three terminals and a mental join.
Explaining unfamiliar tooling. A Helm chart somebody else wrote, a Dockerfile with build stages
you did not design, an IAM policy document. Understanding costs time, and an explanation you can check
against the file is a real saving.
Generating the command you half-remember. The jq filter, the kubectl selector syntax, the aws
CLI flag. Faster than the documentation, and you read it before running it.
Drafting the write-up. After the incident, from the commands and output in the session. This one is consistently undervalued and is the difference between an incident that produces a document and one that produces a vague memory.
What it does not help with: deciding. Whether to roll back, whether to fail over, whether the risk of acting exceeds the risk of waiting. Those are judgements about the business and the blast radius, and the fact that an agent will offer an opinion does not make it a good place to get one.
The productive split: let it do the reading, keep the deciding. That is the same division as everywhere in this pillar, and operational work is where the stakes make it clearest.
Mental model
Section titled “Mental model”A terminal agent is excellent at understanding what is happening and must not be the thing that decides what to do about it. Reading is free; acting is a decision with a blast radius, and the approval prompt exists so that decision stays yours.
What you learned
Section titled “What you learned”- The agent inherits your shell, so its permissions are your permissions
- Separate shells for agent work and production operations
- Establish which cluster and account you are in before starting
- State “read-only until I ask” at the beginning of an operational session
- Use dry runs and plans as the preview, and read them yourself
- Logs contain customer data; an agent reading them sends them to a provider
- Workflow file edits are privilege changes and belong in review
- Allow
shell(gh)separately fromshell(git);ghcan write - Infrastructure changes belong in a reviewed pipeline, not an interactive session
Exercise
Section titled “Exercise”Use a development environment. Nothing here touches production.
-
Check
kubectl config current-contextand your cloud identity. Predict: are they what you expected? -
Start a session with read-only shell commands allowed and nothing else. Ask it to diagnose a deliberately broken deployment. Predict: does it stay read-only?
-
Ask for a fix. Predict: does it propose the command, or try to run it?
-
Ask for the dry-run version first. Compare what you learn.
-
Break a workflow deliberately and ask it to diagnose from
gh run view --log-failed. Predict: does it find the failure faster than you would? -
Ask it to fix the workflow. Predict: should that change go through review? Who owns
/.github/? -
Review your shell’s environment variables. Predict: is there anything in there an agent should not have?