Repo Design Patterns for AI-Assisted Dev: Control Loops, Hooks, and Memory
February 9, 2026·4 min read
A lot of “AI-assisted dev” content is really about prompts.
This post is about repos.
If you want AI help without the config nonsense, drift, or tool slowness, the trick is to treat your repository like a control system:
- The agent is the actuator.
- Tests, CI, and review rules are feedback.
- Hooks are enforcement.
- A memory/task system turns “what we learned” into reusable state.
This is the set of patterns I’ve converged on building Loom (services/loom-core, services/loom) and using it across multiple assistants (Codex, Claude, Gemini, VS Code MCP, etc.).
The Thesis: A Repo Is a Control System
If you can’t explain the loop, you don’t have a process. You have vibes.
A good AI-assisted repo has an explicit loop like:
- clarify intent + constraints
- implement smallest vertical slice
- run fast checks locally
- run real tests
- record decisions + open questions
- ship (or stop)
Everything else is supporting machinery.
Pattern 1: Instruction Hierarchy (AGENTS.md)
The biggest quality jump is an instruction hierarchy that does not depend on chat history.
In this workspace the convention is:
- root
AGENTS.mddescribes cross-repo rules - each major project has a local
AGENTS.mdfor project-specific guidance - optional
AGENTS.local.mdis gitignored for personal overrides
This has a few properties that matter operationally:
- It’s reviewable and versioned.
- It’s discoverable by any tool/agent.
- It makes “how we work here” part of the repo, not tribal knowledge.
Concrete example: loom-core’s AGENTS.md doesn’t just say “run tests”. It lists the daemon model, config flow, and how mcp-agent-context should be used.
Pattern 2: Agent Control Structures as Workflows
Agents need a control structure. “Loop until done” is not a control structure.
The simplest reliable structure I’ve used is a workflow graph with explicit gates:
- start session
- recall context
- implement
- test
- precommit checks
- commit
- push/CI
- end session + summarize
In this workspace, those are encoded as workflow definitions under .agents/workflows/.
Here’s the core idea from .agents/workflows/feature-dev.yaml:
steps:
- id: init
tool_name: agent_session_start
- id: recall
tool_name: agent_context_recall_enhanced
depends_on: [init]
- id: implement
step_type: approval
depends_on: [recall]
- id: test
step_type: approval
depends_on: [implement]
- id: end
tool_name: agent_session_end
depends_on: [push]
This is the important part: your workflow is a state machine.
Even if you’re solo, the gates matter because they force the agent (and you) to acknowledge state transitions:
- “Implementation complete. Tests passing?”
- “Pre-commit checks clean?”
That reduces silent failure.
Pattern 3: Hooks Are Enforcement, Not Advice
Humans forget.
Hooks don’t.
In services/loom-core, sync profiles explicitly include extra generated files like settings.json because lifecycle hooks are part of the system, not optional UX.
From pkg/sync/manager.go:
ExtraGeneratedFiles: []string{"settings.json"}, // Lifecycle hooks
SyncGeneratedOnly: true,
The design goal is “enforce the loop without making it heavy”. A good hook is fast and local:
- formatting/lint in fast mode
- typecheck
- a small, deterministic test subset
Example pattern (from loom-core’s scripts/hooks/pre-commit):
gofmtstaged filesgo vet ./...go build ./...golangci-lint --fast(optional)
That’s the right shape: enforce invariants, avoid 5-minute hooks.
Pattern 4: Shared Memory + Tasks (mcp-agent-context)
If you’re doing real work, you need a memory layer.
I use mcp-agent-context for two things that are easy to underestimate:
- continuity: decisions + findings persist across sessions
- work management: tasks are a first-class queue, not an afterthought
The quick-start loop (from loom-core AGENTS.md) looks like:
1. agent_session_start(namespace="project/feature-x")
2. agent_context_recall_enhanced(query="feature-x")
3. agent_task_add(tasks=[{title: "..."}])
4. agent_context_add(entries=[{entry_type:"decision", ...}])
5. agent_task_update(task_id="...", status="completed", resolution="...")
6. agent_session_end(summarize=true)
A key detail: agent_context_add requires an embeddings key.
That’s intentional. It’s what makes recall usable. But it also means you should treat agent-context as a focused capability, not something every repo needs on day one.
How To Keep It Fast (Avoid MCP Slowness)
MCP feels slow when you design the system around micro-calls.
The fix is architectural:
- Use fewer tools with higher leverage.
- Avoid “agent asks a tool for every line it wants to change”. Let the agent edit locally and then validate with tests.
- When you do use MCP, prefer Loom-mode: a single stdio entrypoint (
loom proxy) routed throughloomd. - Bound output sizes, paginate list/search tools, and make failure states explicit.
This is why Loom’s architecture is boring on purpose: registry -> generate -> sync -> drift visible -> reload.
Tutorial Repo: Clone-and-Try (No Config Archaeology)
I’m publishing a companion tutorial repo for experienced devs who want to try these patterns without committing to a full MCP setup:
- Repo:
services/ai-assisted-dev-starter - Theme: docs-to-code refactor
- Artifact: a tiny workflow interpreter CLI (
workflowctl) + tests + hooks
Two paths:
Path A: No MCP (default)
- Use
AGENTS.md+ the workflow file +make verify. - Works with any assistant.
Path B: Minimal Loom-mode MCP (optional)
- Adds
mcp-agent-context(tasks/memory) andmcp-git. - Uses a minimal
mcp/context/registry.yamland a one-command sync.
The point of Path B is not “more tools”. It’s less drift.
Anti-Patterns (Seen in the Wild)
- No tests, no gates, no decision log.
- Everything is in chat history.
- Hooks that take minutes, so everyone disables them.
- A zoo of MCP servers where every platform sees a slightly different world.
If you adopt one thing from this post, adopt the loop.
Closing: The HUD/Overlay Is the UI Version of the Loop
Once the repo structure is solid, the next win is observability.
Loom’s HUD is a local control plane for agents, tasks, workflows, and server health. On macOS you can optionally enable a native overlay so the system stays visible while you work.
The pattern is the same as the repo patterns above:
- make state visible
- make drift visible
- make transitions explicit
That’s how AI-assisted dev becomes boring enough to trust.
Related Articles
Comments
Join the discussion. Be respectful.