An operating system for coding agents
Coding agents are great for an afternoon and mediocre for a quarter. Here’s the small set of files and rules — with the actual configs —…
An operating system for coding agents
Photo by Igor Saikin on Unsplash
Coding agents are great for an afternoon and mediocre for a quarter. Here’s the small set of files and rules — with the actual configs — that keeps quality from decaying across months and thousands of edits.
The first session with a coding agent is crisp: it reads the code, makes a clean change, writes a test. By the thirtieth, something has rotted — it re-discovers the same files, contradicts a decision it made three weeks ago, guesses the test command, and quietly stops writing tests because nobody made it. The fix isn’t a better model. It’s an operating system around the model: a constitution, an autonomy boundary, tiered context, durable memory, a review panel, and a post-edit hook. Below are the concrete artifacts.
The four things that decay (and the artifact that fixes each)
decays · symptom · fix
- discipline — skips tests, expands scope · a constitution it reads every session
- context — re-learns the repo badly · tiered
CONTEXT.md, maintained by a hook - memory — repeats corrected mistakes · durable per-fact memory files
- review — one blind spot applied uniformly · a multi-lens agent panel
1. A constitution (CLAUDE.md / AGENTS.md)
A lean, always-loaded file stating the non-negotiables: the workflow (Plan → Document → Implement → Test → Review → Commit), the autonomy boundary, the quality bars (tests in the same diff, no dead code, conventional commits), and adapter discipline (no vendor SDK in domain code). Keep it short — it’s read on every turn, so every line costs context budget.
2. An autonomy boundary, not a kill switch
The highest-leverage single decision: let the agent run free on everything reversible, pause only on the two things that aren’t — pushing to a remote and deploying. As a permissions config:
{
"permissions": {
"allow": ["Read","Edit","Write","Grep","Glob",
"Bash(git add:*)","Bash(git commit:*)",
"Bash(npm test:*)","Bash(npm run:*)","Bash(npm ci:*)","Bash(pytest:*)"],
"ask": ["Bash(git push:*)","Bash(npm publish:*)","Bash(aws:*)","Bash(terraform apply:*)","Bash(kubectl apply:*)"],
"deny": ["Bash(git push --force:*)","Bash(git push -f:*)","Bash(*--no-verify*)"]
}
}
Now it works for an hour and commits a dozen times; you review at the push, not at every keystroke. The blast radius of “autonomous” stays bounded because the irreversible ops are the only gated ones. (Verify your runner’s match semantics — prefix vs substring differ — so --no-verify/--force denials and npm publish actually trip; broad globs like npm:* quietly allow npm publish.)
3. Tiered context the agent maintains
One giant context file rots and blows the budget. Tier it:
- Root
CONTEXT.md— the map: what this is, how to run/test, one-line module index, invariants, where state lives. Cap ~200 lines; the session-start read. - Per-module
CONTEXT.md— responsibility, key files, deps, gotchas, how to test just this module. Read before editing that module. **DECISIONS.md** — append-only: date, decision, why, alternatives rejected.
Rule: stale context is a bug, fixed in the same change that invalidated it — not “later.”
4. Durable memory + a tiny knowledge graph
Context describes the code; memory holds what the code can’t tell you across sessions — one fact per file, indexed:
memory/
MEMORY.md # index: one line per fact
user-prefers-X.md # type: user | feedback | project | reference
graph.jsonl # {from, rel, to} — modules/decisions as nodes; depends-on/adapts/supersedes
The graph answers the question agents are worst at: “what breaks if I change this?”
5. A review panel, not a reviewer
Instead of one self-review, run focused sub-agents in parallel, each one lens, strict output:
product — solves the stated problem? scope creep? (plan stage)
architect — correctness, data model, failure modes, coupling
infra — resource limits, deploy/rollback, resilience
security — authz, input validation, secrets, audit trail
test-eng — is the suite real, or happy-path theater? (per change)
→ each returns: [BLOCKER|MAJOR|MINOR] (confidence%) — file:line — issue — fix ; VERDICT
Only high-confidence BLOCKER/MAJOR gate. Diverse lenses catch what a single pass misses; the confidence threshold keeps it from drowning you in nits.
6. A post-edit hook so nothing drifts silently
The piece that ties it together — fires after every edit and emits a checklist (a PostToolUse hook):
Wire it in settings.json, pointed at a tiny script:
{ "hooks": { "PostToolUse": [
{ "matcher": "Edit|Write|MultiEdit",
"hooks": [ { "type": "command", "command": "python3 .claude/hooks/post-edit.py" } ] } ] } }
# .claude/hooks/post-edit.py — reads the tool event on stdin, emits a checklist as context
import json, sys
ev = json.load(sys.stdin)
path = ev.get("tool_input", {}).get("file_path", "the edited file")
checklist = (f"Post-edit refresh for {path}: (1) update the nearest CONTEXT.md if responsibility/"
"key-files/gotchas changed; (2) append a memory/graph edge on a dep/API change; "
"(3) log a DECISIONS.md line on a precedent; (4) update memory on a durable fact. "
"Make these edits in THIS change — stale context is a bug.")
print(json.dumps({"hookSpecificOutput": {"hookEventName": "PostToolUse", "additionalContext": checklist}}))
It emits a checklist; the agent makes the edits in the same diff — reviewable, not a silent rewrite.
It’s a reminder, not a silent rewriter — you always see what it changed.
The loop, in one line
session start: read root CONTEXT.md + MEMORY.md
per task: plan → panel reviews plan → you approve →
implement subtask (tests in same diff) → panel reviews diff →
full test+lint → commit → hook refreshes context/memory/graph → next
only stops: push and deploy
Anti-patterns
- No autonomy boundary — either you babysit every keystroke, or it pushes/deploys unreviewed.
- One mega context file — rots, and blows the budget on every turn.
- Context updated “later” — it’s never later; make staleness a same-diff bug.
- One self-review — one blind spot, applied uniformly; use a panel of lenses.
- A hook that silently rewrites docs — you lose the reviewable trail; emit a checklist, edit in the diff.
The takeaway
We’ve crossed from “AI writes a function” to “AI runs a project for weeks.” The bottleneck moved from can the model code to can the surrounding system keep it honest, oriented, and reviewed over time. A constitution, an autonomy boundary, tiered context, durable memory, a review panel, and a post-edit hook are cheap to set up and compound every session — the difference between an intern who’s brilliant for an afternoon and an engineer who gets better at your codebase every week.
I will be packaging this as a drop-in kit.
Part of a series on running LLM systems in production.
메타데이터
- post_id
- e2f37e67332d
- slug
- an-operating-system-for-coding-agents-e2f37e67332d
- url
- https://medium.com/@varunjindal9/an-operating-system-for-coding-agents-e2f37e67332d
- canonical_url
- https://medium.com/@varunjindal9/an-operating-system-for-coding-agents-e2f37e67332d
- author_url
- https://medium.com/@varunjindal9
- status
- ok
- fetched_at
- 2026-06-11 18:57:12