The most ambitious instruction you can give an agent is not a feature. It is a property the system must keep.
The Sanskrit word dharma is usually translated as duty, religion or righteousness. None of these is quite right. The word comes from the root dhṛ, to hold or to sustain. The Mahabharata puts it plainly: dharma is called dharma because it holds things together.
Older still is the Vedic idea of ṛta, the order that keeps the world running. Rivers flow downhill. Dawn returns. The seasons turn. In the Rigveda, Varuṇa is the guardian of ṛta, and he keeps watch over the world through his spies.
I think about these two words whenever I see a backlog.
Karma versus dharma
A ticket is an act. Fix this crash. Add this field. Speed up this endpoint. It has a beginning and an end, and once it is closed nobody looks at it again.
A system’s dharma is different. It is what must keep holding while a thousand tickets come and go. Every request is authorised. Every payment reconciles. p99 latency stays under 300 milliseconds (99 of every 100 requests finish within that time). No release goes out with a known critical vulnerability. Nobody closes these. They are kept, or they are broken.
Most agent work today is ticket work. We hand over acts, one at a time, and the agent performs them. Now imagine the alternative. Instead of asking an agent to fix each crash as it is reported, you ask it to keep the apps crash-free.
That second instruction is shorter than the first, and enormously more ambitious. It moves the agent from karma to dharma: from performing acts to sustaining an order.
Altitude is earned, not prompted
Here is the part that is easy to miss. “Keep the app crash-free” is useless as a prompt on its own. It only works once three things are in place:
- the agent could fetch crash reports on its own;
- it could map any app version to the exact git commit;
- it had access to Windows, macOS and Linux machines to reproduce and verify each fix.
In other words, you give the agent Varuṇa’s spies. Senses to see when the order is breaking, and hands to restore it.
This is why I say altitude is not a prompting style. It is an engineering investment. Before an agent can own an invariant, it needs:
- Telemetry it can read. Logs, metrics, traces and error reports, queryable without a human in the loop.
- Provenance. From any running build back to the commit, the dependency versions and the config that produced it.
- Reproducible environments. A way to recreate the failure on demand, on the platform where it happens.
- A safe path to change. Branches, CI, staged deploys and automatic rollback.
- An oracle for the invariant itself. A check that says, mechanically, whether the order holds right now.
Miss any one of these and the agent is back to doing tickets, only with grander language.
Choosing a system’s dharma
When I run this exercise with teams, I ask them to name three to five invariants for one service. The good ones share three traits: they are stated as properties, not tasks; they can be checked by a machine; and a breach is unambiguous.
Some that work well:
- Correctness: every ledger entry has a matching counter-entry; every ingested document produces a graph that conforms to its SHACL shapes (SHACL is a W3C language for stating rules a knowledge graph must satisfy).
- Performance: p99 latency under a stated bound; cost per thousand requests under a stated bound.
- Security: zero high-severity findings in static analysis (tools that scan source code for flaws without running it); no secrets in the repository; every endpoint behind an authorisation policy.
- Compatibility: the public API contract does not change without a version bump; database migrations are backward compatible for one release.
Notice that none of these needs an AI to check. That is deliberate. As I argued in “Don’t Grow Brains Where Bones Would Do”, the check should be deterministic wherever it can be. The agent reasons about how to restore the invariant. The code decides whether it has been restored.
Standing agents, bounded autonomy
Once an invariant has its senses, its hands and its oracle, the agent stops being a task runner and becomes a standing guardian. It runs on a schedule or on a signal. It notices a breach, investigates, proposes a fix, proves it and raises a pull request.
How far it goes alone is a separate decision, and it should be made per invariant, not per agent. Restoring a latency budget by tuning a cache is low risk. Changing an authorisation policy is not. In my Bounded Autonomy series I described the mechanisms for this: policy as code (access rules written as versioned, testable code), workload identity (each agent and service carries a verifiable identity instead of a shared secret), durable execution (long-running work that survives crashes and resumes where it stopped) and tamper-evident audit trails (logs that reveal any later alteration). They apply here directly. The higher the altitude, the more the bounds matter.
For the Weekend
Pick one service. Write down three invariants it must hold. For each, list which of the five pieces of plumbing above is missing.
Example. Suppose the service is an order-ingestion API. Start by writing its dharma down as a registry the agent can read but not edit:
# invariants/registry.yaml (protected path: humans only)- id: INV-ORD-01 statement: Every accepted order reaches the warehouse system within 5 minutes check: invariants/order_reaches_warehouse.sql agent_may_fix: false # money and stock involved: propose only- id: INV-ORD-02 statement: p99 latency of POST /orders stays under 400 ms check: invariants/orders_latency_p99.promql agent_may_fix: true # low risk: tune, test, merge behind review- id: INV-ORD-03 statement: No schema change breaks the three downstream consumers check: tests/contracts/ agent_may_fix: false
Each check is mechanical. The first is a SQL query that should always return zero rows:
-- Orders accepted more than five minutes ago with no warehouse receiptSELECT o.order_id, o.accepted_atFROM orders oLEFT JOIN warehouse_receipts w ON w.order_id = o.order_idWHERE o.accepted_at < now() - interval '5 minutes' AND w.order_id IS NULL;
The second is PromQL, the query language of the Prometheus monitoring system, and it should always be true:
histogram_quantile(0.99, sum by (le) (rate(http_request_duration_seconds_bucket{route="/orders"}[5m]))) < 0.4
Now audit the plumbing for each invariant:
| Invariant | Telemetry | Provenance | Reproduction | Safe change path | Oracle |
|---|---|---|---|---|---|
| INV-ORD-01 | Missing: no trace ID links an order to its warehouse receipt | Present | Missing: no replay of a single order | Present | Present (SQL) |
| INV-ORD-02 | Missing: agent cannot query Prometheus | Present | Present (load test) | Present | Present (PromQL) |
| INV-ORD-03 | Not needed | Present | Present | Present | Missing: no contract tests yet |
Four gaps. Close them as ordinary tickets. Only then write the standing agent’s instruction, run as a scheduled task every 15 minutes:
USER STORYAs the on-call engineer for order ingestion, I want an agent to watch theservice's invariants continuously, so that breaches are found andevidenced before customers notice them.DEFINITION OF READY- invariants/registry.yaml exists, and every check in it runs.- Read access to order trace IDs, logs and Prometheus metrics.- A sandbox in which a single order can be replayed.DEFINITION OF DONE (on each run, every 15 minutes)- Execute every check in the registry. If all pass, log "all invariants hold" and stop.- On a breach: collect evidence, reproduce it in the sandbox if possible, and write a failing test that captures it.- If agent_may_fix is true: fix it on a branch, show the failing test now passes, and open a pull request.- If agent_may_fix is false: open an issue with the evidence and a proposed fix, and page the on-call engineer.- You MUST NOT edit anything under invariants/ or tests/contracts/.DEFINITION OF SUCCESS- Every breach has an issue or a pull request within 30 minutes of first detection.- The agent's history shows zero changes to protected paths.- Monthly review: no breach was first reported by a customer.
That list is your real altitude roadmap. The prompt is the easy part. The table above is the real work.