Skip to content

Agent Setup and Configuration

Sanjeev Azad edited this page Jun 1, 2026 · 3 revisions

Agent Setup & Configuration

Status: Complete · [Contributions Welcome ✍️] — share your guardrails files and persona prompts. The practical wiring behind the Digital Org Chart.

Principles need plumbing. This page is the copy‑paste starting point: repo scaffold, the guardrails file that encodes your non‑negotiables, persona prompt templates, and how to wire the Guardian sandbox and the self‑healing loop.

SAE is tool‑agnostic — the primitives below work in any AI‑native IDE. The guardrails file is named .cursorrules in Cursor and CLAUDE.md in Claude Code; the prompts are the same. A dedicated Claude Code track below maps each SAE mechanic to a concrete Claude Code primitive (subagents, slash commands, hooks) — including one (subagents) that turns Adversarial Independence into a structural guarantee.


1 · Repo scaffold

The AI‑hygiene layout, ready to clone:

📂 project/
├── 📄 .cursorrules            # guardrails — for Cursor
├── 📄 CLAUDE.md               # guardrails — for Claude Code (same content)
├── 📁 .claude/                # Claude Code config (optional)
│   ├── 📁 agents/             #   the personas as subagents (e.g. guardian.md)
│   ├── 📁 commands/           #   lifecycle phases as /spec, /guard, /reconcile
│   └── 📄 settings.json       #   hooks — e.g. the blast-radius gate
├── 📁 specs/                  # source of truth — one file per bounded context
│   └── 📄 <slice>.md
├── 📁 src/
│   └── 📁 features/
│       └── 📁 <slice>/        # one bounded context
│           ├── schema.sql
│           ├── routes.ts
│           └── view.tsx
├── 📁 tests/                  # Guardian's domain
└── 📄 README.md

2 · The guardrails file (.cursorrules / CLAUDE.md)

Drop this at the repo root — as .cursorrules for Cursor, or CLAUDE.md for Claude Code. The content is identical; it encodes the non‑negotiables once so you never re‑type them:

# === SAE GUARDRAILS ===

## Source of truth
- specs/<slice>.md is authoritative. If code and spec disagree, the spec wins.
  Flag the conflict; never silently diverge.
- Do not change behaviour without a corresponding spec change.

## Bounded contexts
- Work only inside src/features/<slice>/. Never read or modify another
  context's internals — use an explicit contract (event, shared type, or API).

## File hygiene
- Single responsibility per file. Soft ceiling ~100 lines.
- Prefer cohesion over hitting a line count; do not fragment tightly-coupled logic.

## Vertical slices
- Generate schema + API + state + UI together, driven by one spec.

## Security
- Never output secrets. Read them from env/secret store only.
- Validate and sanitize all external input.
- Enforce the authZ rules named in the spec; never assume they exist.
- Do not add dependencies without flagging them for review.

## Irreversibles (require explicit human approval — never auto-apply)
- auth changes, payment logic, data deletion, schema drops, external sends.

## Output discipline
- Change only what the task requires. Flag any unrequested change.
- After a change, state what you altered and which spec section it maps to.

Adapt the language/framework specifics, but keep the five sections — they map directly to the five non‑negotiables.


3 · Persona prompt templates

The same model can play all three roles in separate sessions. The separation is what matters — see one persona, one job.

Engineer

You are the Engineer. Read specs/<slice>.md and the files in
src/features/<slice>/ only. Implement the vertical slice to satisfy the
spec, honouring every edge case. Obey .cursorrules. Generate the structure
first for my review, then the implementation. After, list what you changed
and the spec section each change maps to.

Visualizer

You are the Visualizer. From the UI section of specs/<slice>.md, produce
clean, semantic, accessible components. Use the project's design tokens.
No business logic — emit only the view layer and the props/contract it
needs from the Engineer.

Guardian (run in a FRESH context — no memory of how the code was written)

You are QA. Your job is to BREAK the <slice> slice, not approve it.
Assume it is wrong and find why. Write integration tests for every edge
case in specs/<slice>.md, PLUS hostile inputs the spec didn't mention
(injection, oversized payloads, concurrency, auth bypass, degraded
dependencies). Default to "broken" when uncertain. Report every failure.

4 · The Claude Code track

Claude Code maps onto SAE unusually cleanly — its primitives line up almost one‑to‑one with the framework, and one of them (subagents) gives you Adversarial Independence (P3) as a structural guarantee rather than a discipline you have to remember.

SAE mechanic Principle Claude Code primitive
Guardrails file P2 · P4 CLAUDE.md (project memory, loaded every session)
The personas Subagents.claude/agents/<name>.md
The writer never judges its own work P3 a Guardian subagent — runs in its own isolated context
Gate the irreversible P5 a PreToolUse hook that escalates risky edits to you
Lifecycle phases as one‑keystroke ops Slash commands.claude/commands/<name>.md
Self‑healing telemetry MCP servers
The Conductor's review‑before‑execute P6 plan mode

Guardrails → CLAUDE.md

Put the SAE Guardrails above into a CLAUDE.md at the repo root. Claude Code loads it into context at the start of every session, so the non‑negotiables are always present. Project CLAUDE.md is checked into git; personal overrides go in ~/.claude/CLAUDE.md.

Personas → subagents

A subagent is a Markdown file with YAML frontmatter where the body is its system prompt — and, critically, it runs in its own isolated context window. That isolation is exactly what the Guardian needs: it sees the spec and the code, but never the Engineer's reasoning.

.claude/agents/guardian.md:

---
name: guardian
description: Adversarial QA. Use after any non-trivial change to try to BREAK the slice — never to write code.
tools: Read, Grep, Glob, Bash
model: inherit
---
You are the Guardian — adversarial QA. Your job is to REFUTE the change, not approve it.
Read specs/<slice>.md and the slice's code, then write and run integration tests for
every edge case in the spec PLUS hostile inputs it didn't mention (injection, oversized
payloads, concurrency, auth bypass, degraded dependencies). Default to "broken" when
uncertain. Report every failure and the spec clause it violates.

Two SAE mechanics fall out of this for free:

  • No Write/Edit in tools → the Guardian physically cannot modify the code it judges. It runs tests and refutes; it never fixes.
  • Isolated context → the writer never judges its own work (P3). Add isolation: worktree to the frontmatter to also hand it a throwaway copy of the repo — a true sandbox.

The Engineer and Visualizer can be subagents too, or just the main session — the separation that matters most is the Guardian's. (The Conductor is always you.)

Only name and description are required. tools is a comma‑separated allowlist (omit it to inherit every tool); model accepts sonnet/opus/haiku/a full ID/inherit.

Lifecycle phases → slash commands

Encode the loop's phases as commands so each is one keystroke.

.claude/commands/guard.md:

---
description: Adversarially verify a slice with the Guardian
argument-hint: [slice]
---
Use the **guardian** subagent to verify the `$1` slice against specs/$1.md.
It must try to break the slice and report every failure. Do not let it edit code.

.claude/commands/spec.md — a gated command (Claude can't auto‑run it):

---
description: Author or update the bounded-context spec BEFORE any code
argument-hint: [slice]
allowed-tools: Read, Edit, Write
disable-model-invocation: true
---
Open or create specs/$1.md. Capture the data model, API, UI, and — above all — the
edge cases and acceptance criteria. Do not touch code in this step.

Arguments are $ARGUMENTS (the whole string) or $1, $2 (positional). disable-model-invocation: true keeps side‑effectful phases (/spec, /ship) manual‑only — you choose when they run. You can also embed live context with !`shell command` and file contents with @path.

Gate the irreversible → a PreToolUse hook

P5 says auth, payments, deletion, and schema changes are never auto‑applied. A PreToolUse hook turns that rule into enforced policy — it inspects every Edit/Write and escalates a high‑blast‑radius change to you instead of letting the agent apply it.

.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          { "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/blast-radius-gate.sh" }
        ]
      }
    ]
  }
}

.claude/hooks/blast-radius-gate.sh:

#!/bin/bash
input=$(cat)
file=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')
if printf '%s' "$file" | grep -qiE '(auth|payment|billing|/migrations?/|schema\.|\.sql$)'; then
  jq -n '{hookSpecificOutput:{hookEventName:"PreToolUse",
          permissionDecision:"ask",
          permissionDecisionReason:"Blast-radius gate (P5): touches auth/payments/schema — human approval required."}}'
fi
exit 0

The hook receives the tool call as JSON on stdin. Returning permissionDecision: "ask" forces a human prompt — the agent proposes, you decide; use "deny" to hard‑block instead. (Equivalently, a script can exit 2 to block with a message on stderr.)

Self‑healing loop → MCP

Wire the self‑healing loop by giving the agent read‑only access to your telemetry and database through MCP servers — project scope, shared via .mcp.json (or claude mcp add --scope project …). The agent reads the trace, drafts a spec amendment, and the same PreToolUse gate stops the fix from auto‑applying to anything irreversible. Plan mode is the Conductor's natural review step before any of it executes.

Verified against the current Claude Code docs (subagents, slash commands, hooks, settings) as of 2026. Field names and the escalate/block mechanism are accurate; if you're on a much older version, confirm against your docs.


5 · The Guardian sandbox

The Guardian runs continuously and adversarially, isolated from production:

  • A containerized environment with no prod credentials and least‑privilege access.
  • Runs the spec's acceptance criteria as tests on every change.
  • Seeded with hostile fixtures (malformed payloads, boundary values, concurrent writes).
  • Its findings re‑enter the loop at Reconcile — fixes flow through the spec.

The cardinal rule: the context that wrote the code must not be the context that judges it. Spin up the Guardian fresh.


6 · Wiring the self‑healing loop

To make Module 5's feedback circle real:

  1. Capture — structured logging + error/exception tracking in production.
  2. Route — on an exception, ship the stack trace + payload into an agent context.
  3. Diagnose — the agent cross‑references trace ↔ codebase, drafts a spec amendment (root cause).
  4. Gate — you review the amendment. Irreversible‑touching fixes are never auto‑applied.
  5. Re‑run — approved amendment re‑enters the lifecycle at Spec; the Zero‑Ops pipeline ships it.

7 · Model selection

Match the model tier to the Context Entropy of the task — frontier models for high‑entropy architecture and adversarial review, faster/cheaper tiers for low‑entropy mechanical edits. Track the effect on cost per change. Default to the most capable model when a change touches a high‑blast‑radius area, regardless of entropy.

Reality check. Tooling is the easy 20% — copy these templates and you're running in an hour. The hard 80% is the judgment: knowing when the agent is confidently wrong, when a "low‑entropy" change is high‑stakes, and when to stop and spec instead of generate. Configuration removes friction; it does not remove the need for an operator who can actually evaluate the output. See When NOT to Use SAE.


See also: Operator Techniques · Best Practices · Approved Zero‑Ops Tooling List · Getting Started.

Clone this wiki locally