SOUL.md — identity & law
Loaded every turn. Contains persona, iron rules, skill triggers, routing logic. The constitution — it never changes mid-task and overrides everything below it on conflict.
Using AI well is an engineering discipline, not a habit. I built my team's AI delivery system — the pipeline, the gates, the context, the review roles — and it ships real features.
Two views of how the system works — the orchestration pipeline that routes every request, and the memory architecture that makes it remember.
A request flows through six stages — from user input to learned response. The orchestrator decides which models, tools, and memory stores to use at each step.
Every layer earns its token cost. Facts flow from ephemeral session context to permanent knowledge — and nothing important lives in only one place.
Loaded every turn. Contains persona, iron rules, skill triggers, routing logic. The constitution — it never changes mid-task and overrides everything below it on conflict.
Always-loaded facts with a 7-day admission test: still true and useful next week, or it doesn't get in. Behavioral corrections, environment facts, user preferences — compact, high-signal, token-cost forever.
3,700+ entries. Hybrid search (50% vector + 30% FTS5 + 20% importance). Knowledge graph with temporal triples for structured relationships. The long tail — on-demand recall, not always-loaded. Self-maintains via nightly digest and weekly consolidation.
The canonical semantic store. Interlinked markdown knowledge base for deep domain knowledge. Human-authored, human-organized — the agent reads it but doesn't write to it uninvited.
FTS5-backed conversation history. Past sessions are searchable but stay out of the active context. Used for cross-session recall — "what did we do about X" — without polluting the current turn.
Every AI success story you'll read is missing this section. Here's what went wrong in ours — the discipline came from the failures.
The agent found a real bug — one that had sat harmless in production for years — and repaired it. The repair changed behavior other code had quietly grown to depend on, and things blew up. Lesson: an agent evaluates code; it doesn't know your system's history. A harmless bug is load-bearing until proven otherwise.
The requirement was genuinely small — an existing rule needed one more condition, a change the codebase was already shaped for. The agent, not grasping that intent, rebuilt the surrounding flow instead: hundreds of new lines that technically worked and doubled the review burden. Lesson: the smallest correct change comes from knowing what the codebase already wants to do — that judgment is still ours.
Asked for accuracy, the agent updated the database row by row — correct, and an IO storm at our volume. Batching was the obvious answer, but only obvious to someone who has paid for IO before. Lesson: performance instincts don't ship with the model; they come from the scars.
The pattern behind all three: the damage happens when someone can't yet tell a good answer from a plausible one — a junior burning tokens on the wrong question, merging changes they can't explain. So the rule is not "use AI less." It is: discernment first, delegation second. You must be able to judge the problem and the logic before you outsource the typing.
$ workflow run <feature>
prd ✓ proposal ✓ contracts ✓ sdk ✓
tasks → dev → verify
⏸ gate: waiting for human approval…
# AI never commits
An artifact-gated, 10-stage delivery pipeline built as agent skills: requirements document (PRD) → design → contracts → SDK → tasks → parallel agent development → machine-judged acceptance. Every artifact carries a human approval signature, and irreversible actions — publish, push, migrations — require explicit human confirmation.
[chat] @bugdoctor error spike, workflow svc
→ tracing across repos… (MCP: logs + code)
→ hypothesis: stale credential cache
→ evidence: trace id 8f3a · 3 log lines
# hours of triage → minutes
Team-built AI incident diagnoser living in our team chat: symptoms in, trace-backed hypotheses out — reading production logs over MCP and code across every repo, frontend and backend. The real work was making the system diagnosable first: standardized errors, trace IDs through every hop, names that tell you what broke. The bot is the payoff; the discipline is the design.
$ schema build events/*.json
codegen → node ✓ java ✓ rust ✓
publish → sdk v1.0.34
# producers and consumers can't drift
JSON-Schema-first event contracts with multi-language SDK codegen (Node, Java, Rust) — producers and consumers can't drift because the schema is the source of truth.
[chat] @reach send a $10 bonus to users registered on Jan 12
→ target preview ready · audit logged
⏸ waiting for "confirm"…
→ executed · results reported to chat ✓
# preview first · a human confirms · audit always
A LangChain agent living in our team chat: operations asks in natural language, the agent resolves the target audience, shows a preview, and executes only after an explicit "confirm" — every step audit-logged. The same gate philosophy as everything else I build.
$ agent task "add a field to the contract"
→ repo resolved (1 of 17) · context loaded
→ memory: prior decisions recalled
# the prompt is engineered context, not clever words
Clever prompts don't scale; engineered context does — a routing manifest across 17 repositories, 30+ per-service context files, and persistent memory across sessions. The agent starts every task already knowing the codebase.
A one-line feature request walks through ten stages, each invoked as /workflow-<stage>. There is no state.json — every stage derives its state from the presence and content hash of the artifact the previous stage wrote, and refuses to run until that artifact exists and is approved.
[to confirm] instead of guessing..proto contracts and publish the shared gRPC types.Artifact-gated, human-approved, contract-first. Contracts are generated and shared before a line of code is written — so producers and consumers can't drift.
Each stage — and each reusable building block — is a skill: a Markdown file the agent reads before it acts. This is a real excerpt from graceful-shutdown, the policy every backend service must satisfy before it's called production-ready. It came out of a real incident.
Real excerpt from the ai-native-sdlc repo — desensitized (neutral service names, no company internals).
# Graceful Shutdown — Monorepo Default Policy
# A service is "graceful-restart capable" iff all six hold:
1. Signal binding. Listen for SIGTERM → enter draining state, do not exit.
2. Two-stage drain. Flip health probe to NOT_SERVING first, wait one
readiness period so the load balancer stops sending traffic, then drain.
3. In-flight wait. Stop accepting new connections; let in-flight
requests finish, bounded by a timeout < terminationGracePeriodSeconds.
4. Background workers drained. Consumers, tickers, span processors
all observe the shutdown signal and exit cleanly.
5. Connection cleanup. DB / Redis / upstream pools closed after the
server stops; telemetry flushed last.
6. K8s manifest aligned. terminationGracePeriodSeconds ≥ drain + buffer.
# If verification can't be done, say so in the PR —
# do not claim "graceful shutdown done" on code review alone.
The skill also ships stack-specific templates (Rust, NestJS, Node, Java), the K8s manifest, a local SIGTERM test, and a list of anti-patterns to reject in review. Twenty-three skills like this live in the repo — the ten pipeline stages plus reusable blocks.
The pipeline dispatches role-specialized subagents, each with a tight remit and its own tool budget. Here is the real remit of code-reviewer — one of twelve.
Real excerpt from the ai-native-sdlc repo — the agent's own definition file.
# Role: senior code reviewer. Correctness, security, performance,
# maintainability — with constructive, specific feedback.
When invoked:
1. Identify the scope of changes and the language/framework.
2. Read the changed code in full, plus enough context to judge correctness.
3. Review in order: correctness → security → performance
→ maintainability → tests → docs.
4. Produce prioritized, actionable feedback with file/line references.
Severity:
CRITICAL security or data-loss risk — BLOCK merge.
HIGH real bug or broken contract — fix before merge.
MEDIUM maintainability / minor correctness — fix when practical.
LOW style, naming — optional.
# Be specific, be brief, be kind.
The full roster is twelve: planner, product-owner, microservice-architect, code-architect, backend-developer, frontend-developer, data-layer-reviewer, code-reviewer, qa-expert, security-auditor, technical-writer and harness-optimizer. Each one draws a boundary; none of them can approve its own work.
All of it operates under one standing rule set — a desensitized set of Karpathy-derived guidelines that bias toward caution over speed.
The whole pipeline — 10 stages, 23 skills, 12 agents — lives on GitHub, desensitized and MIT-licensed. What you've seen here is a few samples; the rest is in the open.
Both of my agents — the one at work and the one at home — run under the same standing rules. Every one of them was written the hard way.
Slow is fine. Wrong is not.
The Lab page shows what my home agent does. This is how it got that way — the same method I use on the agents at work, run twice, converging on the same constitution.
On day two of the agent's life I installed SOUL.md — its identity file: problem-solving protocol, naming rules, behavioral law — before it did any real work. Rules don't retrofit well.
New agent, small scope. I watch where it stalls or overreaches, then widen. It's the same calibrated-challenge ladder I use on junior engineers.
It executed without confirmation three times in one session — that same day, "discussion is not permission" became permanent law. Six standing rules; every one has an incident behind it.
After every correction the agent must show the stored entry — ID and content. "Got it" is not evidence that learning happened.
Every always-loaded fact costs tokens forever, so MEMORY.md — the always-loaded layer — has a 7-day admission test: still true and useful in a week, or it doesn't get in. Facts route by weight — behavioral law loads every turn, Mnemosyne holds the long tail for on-demand recall, transcripts stay searchable but out of the way.
The expensive model was over-serving simple execution, so it got demoted to deep-reasoning duty only. An update wiped the config once — pre-update backups went on that day. A nightly memory digest, a weekly consolidation pass, a monthly self-audit: the agent maintains itself, on a schedule.
Two agents, two independent memory stores, one converging constitution. That's when you know it's a method — not a habit.
None of this tooling exists because it's cool. Large language models have a handful of hard constraints — and every piece of my stack is a direct answer to one of them.
A model can only hold so much, so relevance beats volume: a routing manifest across 17 repositories decides where a task belongs, and 30+ per-service context files mean the agent starts already knowing the codebase — instead of re-reading it every session.
The biggest handicap of any agent: session ends, knowledge gone. My answer is layered — an identity file for law, an always-loaded fact file with a 7-day admission test, a vector store (Mnemosyne, 3,700+ entries) for the long tail, and Obsidian as the human-curated layer on top. Facts route by weight; nothing important lives in only one head.
Every dev command an agent runs burns context. A filtering proxy (RTK) strips the noise before the model sees it — 75M+ tokens measured saved. Scheduled scripts that need no judgment run with no LLM at all. At home, a tiered router sends routine work to budget models and saves the heavyweight for deep reasoning. Same principle at every scale: pay for thinking, not for typing.
Models produce answers that look right. That's why nothing merges without a human gate, every memory write shows a receipt, and the failure file above exists. Trust is a budget — spend it on verification, not on hope.
Anything done twice becomes a versioned skill. Some we adopted from the community and adapted — credited, not claimed. Some we built from scratch: the delivery pipeline, the review roles, the repo router. The test is always the same: would a new teammate — human or agent — do this right on day one?
The stack will change. The constraints won't. Build for the constraints.